算法为编程语言的基础

技术面试中,面试官一般会先就你所应聘的岗位进行相关知识的考察,也叫基础知识和业务逻辑面试。只要你回答的不是特别特别差,面试官通常会说:“咱们写个代码吧”,这个时候就开始了算法面试。也就是说,一轮技术面试=基础知识和业务逻辑面试+算法面试

一次字节跳动面试的感慨

前段时间,我曾面试字节跳动,面试官的一道算法题算是把我给难住了,给大家还原当时的面试场景如下:

面试官:给定单链表的头结点 head,实现一个调整链表的函数,从链表尾部开始,以 K 个结点为一组进行逆序翻转,头部剩余结点不足一组时,不需要翻转。(不能使用队列或者栈作为辅助)

但是这个算法题困扰了我很久,一直苦苦得不出答案。最后还是在面试官的提醒下才知晓正确的答案。

正确答案如下:

我们先定义一个 reverseKGroupPlus() 方法

public ListNode reverseKGroupPlus(ListNode head, int k) { 
 if (head == null || k <= 1) return head; 
 
 // 计算原始链表长度 
 int length = linkedLength(head); 
 if (length < k) 
 return head; 
 // 计算 offset 
 int offsetIndex = length % k; 
 // 原始链表正好可以由 K 分位 N 组,可直接处理 
 if (offsetIndex == 0) { 
 return reverseKGroup(head, k); 
 } 
 
 // 定义并找到 prev 和 offset 
 ListNode prev = head, offset = head; 
 while (offsetIndex > 0) { 
 prev = offset; 
 offset = offset.next; 
 offsetIndex--; 
 } 
 
 // 将 offset 结点子链表进行翻转,再拼接回主链表 
 prev.next = reverseKGroup(offset, k); 
 return head;
}

注意当链表长度正好可以用 K 分位 N 组时,我们直接处理,否者才需要后续复杂的逻辑。

代码的注释足够清晰了,在脑子里过一遍代码的执行流程应该能明白,为了帮助大家理解,我又画了个示意图。

假设以 head 为头结点的链表长度是 10,K 为 4,那么计算下来 offset Index 就是 2。

 

找到 prev 和 offset 结点后,就可以将以 offset 结点为头结点的子链表,进行 K 个一组翻转链表的操作了。

 

此时,head 结点位起始的链表,就是我们计算后的结果。

面试官当时跟我交谈3个小时,说算法其实不算难,而且算法是程序编程的基础之一是一定要掌握的,给我推荐了一本算法笔记。笔记领取方式:关注、转发后私信小编【算法】即可领取

笔记一共分为7个小节,详细叙述了算法的厉害之处。

  1. 排序和查找算法
  2. 查找算法
  3. 二叉树
  4. 队列和栈
  5. 字符串
  6. 数组
  7. 其它算法

 

排序算法

  1. 希尔排序
  2. 原地归并的抽象方法
  3. 自顶向下的归并排序
  4. 自底向上的归并排序
  5. API
  6. 堆的算法
  7. 堆排序

 

查找算法

  1. 无序链表中的顺序查找
  2. 有序数组中的二分查找
  3. 二分查找的分析
  4. 二叉查找树的基本实现
  5. 平衡查找树的基本实现
  6. 红黑树的性质
  7. 散列函数

 

二叉树

  1. 二叉树中序遍历
  2. 二叉树的序列化和反序列化
  3. 子树
  4. 最近公共祖先
  5. 二叉树的层次遍历
  6. 将二叉树拆成链表
  7. 在二叉查找树中插入节点

 

队列和栈

  1. 带最小值操作的栈
  2. 用栈实现队列
  3. 有效的括号序列
  4. 简化路径

 

字符串

  1. 罗马数字转整数
  2. 回文数
  3. 乱序字符串
  4. 有效回文串
  5. 翻转字符串
  6. 最长无重复字符的子串
  7. 字符串压缩
  8. 比较字符串
  9. 编辑距离1I

 

数组

 

 

其它算法

 

 

文末笔记领取方式

笔记领取方式:关注、转发后扫描小编的二维码即可领取

注意哦!一定要转发哦!