本博客解决链表问题
141. Linked List Cycle
要求:链表是否有环
ac:两个指针fast,slow
142. Linked List Cycle II
要求:发现链表是否有环,如果有环,返回环路起始位置
ac:两个指针的问题
237. Delete Node in a Linked List
ac:将下个结点的值赋给当前的结点
83. Remove Duplicates from Sorted List
要求:重复的元素只保留一个
ac:一个指针就可以解决
82. Remove Duplicates from Sorted List II
要求:重复的元素全部删除
ac:这个需要这个算是有点复杂了,需要连续的两个循环操作,
203. Remove Linked List Elements
要求:删除链表中的值等于某个值的结点. 类似的还有数组删除的情况
ac:注意dummy以及删除完列表结点为空的情况
206. Reverse Linked List
要求:链表反转
ac:需要三个指针
public ListNode reverse(ListNode node) {
if (node == null || node.next == null) return node;
ListNode dummy = null;
while (node != null) {
ListNode next = node.next;
node.next = dummy;
dummy = node;
node = next;
}
return dummy;
}
92. Reverse Linked List II
要求:反转部分链表
ac:用到4个缓存结点, 注意连接地方的拼接
234. Palindrome Linked List
要求:判断链表是否回文
ac:反转中点
21. Merge Two Sorted Lists
要求:有序链表合并
ac:归并排序的一部分
61. Rotate List
要求:旋转链表,
错误:空指针异常
ac:先找到长度,再找到新的链表的起点,对端点进行合理的处理
148. Sort List
要求:常数空间
ac:归并与快排
这里给出代码
//归并排序
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode slow = head;
ListNode fast = head;
ListNode pre = null;
while (fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
pre.next = null;
ListNode l1 = sortList(head);
ListNode l2 = sortList(slow);
return merge(l1, l2);
}
public ListNode merge(ListNode l1,ListNode l2) {
ListNode head = new ListNode(0), p = head;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
p.next = l1;
l1 = l1.next;
} else {
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
if (l1 != null) {
p.next = l1;
}
if (l2 != null) {
p.next = l2;
}
return head.next;
}
// hulu
// 链表快排,经常考的
public ListNode void quickSort(ListNode head, ListNode tail) {
if (head != tail) {
ListNode partion = getPartion (head, tail);
quickSort(head, partion);
quickSort(partion.next, tail);
}
return head;
}
public static ListNode getPartion(ListNode beg, ListNode end) {
int key = beg.val;
ListNode p = beg;
ListNode q = beg.next;// quick
while (q != end) {
if (q.val < key) {
p = p.next;
swap(p, q);
}
q = q.next;
}
swap(beg, p);
return p;
}
public static void swap(ListNode p, ListNode q) {
int temp = p.val;
p.val = q.val;
q.val = temp;
}
147. Insertion Sort List
要求:链表的插入排序
思路:每次每次插入的时候找到第一个大于当前结点的值的地方插入
错误:无思路, 忘记更新pre
ac:新建了一个链表
143. Reorder List
要求:给定链表 L0 L1 L2 L3 … LN
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
思路:取到一半,反转另一半然后合并
错误:链表反转部分,指针异常,可以先将pre赋值为null
138. Copy List with Random Pointer
要求:类似于图拷贝。多加了一个随机的指针。
ac:利用hash进行存储,因为下一Node结点还没构建出来,所以要用label一个个构建node结点,进行处理
109. Convert Sorted List to Binary Search Tree
要求:排序链表转二叉搜索树
ac:递归构造,每次取median
86. Partition List
要求:给定输入的链表,规定值,返回链表,小于值的在左边,大与值的在右边
ac:这个地方当时也是忘记了,hulu电话面试也就跪了,另外一种可以是swap的方式
2. Add Two Numbers
要求:实现链表的加法,反向的
错误:在循环中未更新l1 以及 l2, 更新l1 与 l2的时候未进行空指针判断,忘记更新re到re.next
ac:注意carry以及l1 l2的循环条件
445. Add Two Numbers II
要求:正向的加法
思路:1.将链表反转,再加 (速度很快) 2.dfs 3.stack(这里面在处理list的时候,用了一个trick,用了个双指针进行处理)
328. Odd Even Linked List
要求:链表,奇数位的放在前面,偶数位的放在后面
思路:按照奇数个跟偶数个进行区分
ac:bugfree
19. Remove Nth Node From End of List
要求:删除从后面数第N个元素
思路:先行指针,dummy
ac:bugfree
24. Swap Nodes in Pairs
要求:交换两个相邻的两个位置
思路:trick dummy指针的使用 每次进行下一步的判定
ac:注意dummy,仅用一个current即可,要不容易出问题
25. Reverse Nodes in k-Group
要求:与24题类似,将链表以k个为单位进行反转,然后拼接起来。
思路:无思路
ac:利用分治法,每次处理一个k个的结点,然后返回相关的结果,忘记对count计数进行数值的更新
23. Merge k Sorted Lists
要求:k个链表归并,这个地方可以学习到是链表数组,直接认为是链表节点数组即可
ac:直接按照归并做就可以了