链表
链表的注意点
- 出现了环,导致了死循环
- 分不清楚边界,导致边界出错
- 搞不清递归
环
边界
- 当题目中的头节点需要进行操作时,可能会被移除时,要考虑使用虚拟节点,也就是头节点。这样操作就会避免对第一个节点的讨论
前后序
相较于树,在链表中只有一个后续指针,只有前序和后序,没有中序遍历。
如果是前序遍历,那么你可以想象前面的链表都处理好了,怎么处理的不用管。相应地如果是后序遍历,那么你可以想象后面的链表都处理好了,怎么处理的不用管。
- e.g.前序遍历
1 2 3 4 5 6 7 8
| def dfs(head,pre): if not head return pre//递归的结束条件 next=head.next ##此处添加主逻辑 head.next = pre dfs(next,head)
dfs(head,None)
|
一些技巧
头结点————虚拟结点
头结点不需要参与运算,不需要特殊判断
快慢指针
判断链表是否有环以及环的入口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Solution { public boolean hasCycle(ListNode head) { if(head==null||head.next==null)return false; ListNode slow = head; ListNode fast = head.next; while(fast!=null&&fast.next!=null) { if(fast==slow)return true; fast=fast.next.next; slow=slow.next; } return false; } }
|
leetcode题目
Leetcode 61.旋转链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { public ListNode rotateRight(ListNode head, int k) { if(head==null)return head; ListNode pre_newHead = new ListNode(); ListNode temp = new ListNode(); pre_newHead = head; temp=head; for(int i=0;i<k;i++) { if(temp.next!=null) temp=temp.next; else { temp=head; } } while(temp.next!=null) { pre_newHead = pre_newHead.next; temp = temp.next; } temp.next = head; head=pre_newHead.next; pre_newHead.next=null; return head; } }
|
Leetcode 82.删除排序链表中的重复元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { public ListNode deleteDuplicates(ListNode head) { if(head==null)return null; if(head.next==null)return head; ListNode dummyhead = new ListNode(0,head); ListNode q = new ListNode(); ListNode pre = new ListNode(); pre=dummyhead; q=head; while(q!=null) { if(q.next!=null&&q.val==q.next.val){ while(q.next!=null&&q.val==q.next.val) { q=q.next; } pre.next=q.next; } else { pre = q; } q=q.next; } return dummyhead.next; } }
|
此题最为巧妙的是运用了头指针,这样可以减少对第一个元素的讨论。
Leetcode .反转链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public ListNode reverseList(ListNode head) { ListNode cur = head; ListNode pre=null; while(cur!=null) { ListNode nextTemp = cur.next; cur.next = pre; pre = cur; cur = nextTemp; } return pre; } }
class Solution { public ListNode reverseList(ListNode head) { if (head == null || head.next == null) { return head; } ListNode p = reverseList(head.next); head.next.next = head; head.next = null; return p; } }
|
Leetcode 92.反转链表2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { if(head==null)return null; ListNode pre = new ListNode(0,head); ListNode dummy =pre; ListNode cur = head; while(m>1) { pre=cur; cur=cur.next; m--; n--; } ListNode change_begin_pre =pre; ListNode change_begin=cur; ListNode temp=null; while(n>0) { temp = cur.next; cur.next=pre; pre=cur; cur=temp; n--; } change_begin_pre.next=pre; change_begin.next=cur; return dummy.next; } }
|
Leetcode 142.环形链表2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
public class Solution { public ListNode detectCycle(ListNode head) { ListNode slow = head; ListNode fast = head; while(true) { if(fast==null||fast.next==null)return null; slow=slow.next; fast=fast.next.next; if(fast==slow)break; } fast=head; while(fast!=slow) { fast=fast.next; slow=slow.next; } return slow; } }
|
Leetcode 234.回文链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { private ListNode frontPointer;
private boolean recursivelyCheck(ListNode currentNode) { if (currentNode != null) { if (!recursivelyCheck(currentNode.next)) { return false; } if (currentNode.val != frontPointer.val) { return false; } frontPointer = frontPointer.next; } return true; } public boolean isPalindrome(ListNode head) { frontPointer = head; return recursivelyCheck(head); } }
|
Leetcode 143.重排链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| class Solution { public void reorderList(ListNode head) { if(head==null)return ; if(head.next==null)return ; ListNode slow = head; ListNode fast = head.next; while(true) { if((fast!=null&&fast.next==null)||fast==null) { break; } slow=slow.next; fast=fast.next.next; } ListNode temp = slow.next; slow.next=null; temp = reverseList(temp); mergeList(head,temp); } private ListNode reverseList(ListNode head) { ListNode prev = null; ListNode curr = head; while (curr != null) { ListNode nextTemp = curr.next; curr.next = prev; prev = curr; curr = nextTemp; } return prev; } public void mergeList(ListNode l1, ListNode l2) { ListNode l1_tmp; ListNode l2_tmp; while (l1 != null && l2 != null) { l1_tmp = l1.next; l2_tmp = l2.next;
l1.next = l2; l1 = l1_tmp;
l2.next = l1; l2 = l2_tmp; } } }
|
Leetcode 148.排序链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
class Solution { public ListNode sortList(ListNode head) { if (head == null || head.next == null) return head; ListNode fast = head.next, slow = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } ListNode temp = slow.next; slow.next=null; ListNode left = sortList(head); ListNode right = sortList(temp); return merge(left,right); } public ListNode merge(ListNode h1,ListNode h2){ ListNode dummy = new ListNode(-1); ListNode p = dummy; while(h1!=null && h2!=null){ if(h1.val < h2.val){ p.next = h1; h1 = h1.next; }else{ p.next = h2; h2 = h2.next; } p = p.next; } if(h1!=null) p.next = h1; else if(h2!=null) p.next = h2; return dummy.next;
} }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| class Solution { public ListNode sortList(ListNode head) { int length = getLength(head); ListNode dummy = new ListNode(-1); dummy.next = head; for(int step = 1; step < length; step*=2){
ListNode pre = dummy; ListNode cur = dummy.next; while(cur!=null){ ListNode h1 = cur; ListNode h2 = split(h1,step); cur = split(h2,step); ListNode temp = merge(h1,h2); pre.next = temp; while(pre.next!=null){ pre = pre.next; } } } return dummy.next; } public int getLength(ListNode head){ int count = 0; while(head!=null){ count++; head=head.next; } return count; } public ListNode split(ListNode head,int step){ if(head==null) return null; ListNode cur = head; for(int i=1; i<step && cur.next!=null; i++){ cur = cur.next; } ListNode right = cur.next; cur.next = null; return right; } public ListNode merge(ListNode h1, ListNode h2){ ListNode head = new ListNode(-1); ListNode p = head; while(h1!=null && h2!=null){ if(h1.val < h2.val){ p.next = h1; h1 = h1.next; } else{ p.next = h2; h2 = h2.next; } p = p.next; } if(h1!=null) p.next = h1; if(h2!=null) p.next = h2;
return head.next; } }
作者:cherry-n1 链接:https: 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
|