LinkedList
定义
复制代码
1
2
3
4
5
6
7
8
9class ListNode{ int val; ListNode next; ListNode(int val){ this.val=val; this.next=null; } }
注意事项:
1 链表题相对简单,80%以上可以采用递归和双指针来解决;
2 链表头部可能为空、被修改或者被删除的情况下,我们往往需要使用dummy, dummy.next指向头部,最终返回dummy.next即可
3 遍历联表时,应该使用: while(cur!=null)
1 Reverse Linkedlist(出现频率最高)
思路分析
1.1 2根指针思路, dummy + cur;
1.2 cur提前存储next元素,解决了翻转时linkedlist断裂问题;
1.3 dummy用于保存遍历后的头部;
复制代码
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
28public static ListNode reverseListNonRecursive(ListNode head) { // 新建一个dummy ListNode dummy = new ListNode(0); // dummy指向头部,即dummy再head前面 dummy.next = head; // 边界条件;如果head或者head.next是null,直接返回head;即,没有元素或者只有一个元素; if (head == null || head.next == null) return head; // 从第2个node开始遍历;原因:head.next下一步将需要设置为null ListNode curr = head.next; //head.next置为null head.next = null; //从2号node开始遍历,实施如下动作:1 curr.next前指; 2 dummy.nexe指向curr; 3 curr后移 while (curr != null) { //存储curr的next,为curr后移做准备 ListNode tmp = curr.next; //1 curr.next前指 curr.next = dummy.next; //dummy.nexe指向curr dummy.next = curr; //3 curr后移 curr = tmp; } //返回dummy.next; return dummy.next; }
递归实现方式思路图(带入例子1->2->3)
复制代码
1
2
3
4
5
6
7
8
9
10
11public static ListNode reverseListRecursive(ListNode head) { if ( head== null || head.next == null) //边界条件 return head; ListNode secondtNode = head.next;//保存状态为nextNode head.next = null; ListNode reverseRest = reverseListRecursive( secondtNode);//通过递归翻转剩余部分链表,返回翻转后的头部为reverseRest secondtNode.next = head; //2号node前指1号node return reverseRest; }
-------------------------------------------------------------------------------------------------
2 合并链表(进军硅谷P102, 出现频率较高)
两个有序链表, L1、L2合并后得到有序链表L3;
合并两个有序链表,返回合并后的有序表头,不允许利用额外的线性存储空间;
L1-> 5->15->NULL
L2->10->15->20->NULL
原题:
https://leetcode.com/problems/merge-two-sorted-lists/
思路:
1 创建dummy, dummy.next指向新链表第一个节点;同时,为了实现遍历,也要创建cur,cur初始化为=dummy,且随着链表移动;
2 2个指针指向2个输入链表的表头,不为空的情况下,取值较小的节点放入新链表的尾部,直至两个指针至少有一个为空;
3 链表中不位空的部分放到新链表的尾部;
4 返回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/** * Definition for singly-linked list. * public class ListNode { * public int val; * public ListNode next; * public ListNode(int x) { val = x; } * } */ public class Solution { public ListNode MergeTwoLists(ListNode l1, ListNode l2) { if(l1==null) return l2; if(l2==null) return l1; if(l1==null||l2==null) return l1==null?l2:l1; ListNode dummy = new ListNode(0); ListNode cur = dummy;//初始化cur=dummy, //l1,l2任意1个不为null , 使用l1!=null, 而不是l1.next!=null;因为:要走到最后一个元素; while(l1 != null && l2 != null) { if(l1.val <= l2.val) { cur.next = l1;//因为cur初始化为dummy.next l1 = l1.next; } else { cur.next = l2; l2 = l2.next; } cur=cur.next; } //把剩下的list接在l3后面 if(l1!=null) cur.next = l1; else if(l2 != null) cur.next=l2; //返回 return dummy.next; } }
注意:
1 判断链表不为空,使用l1!=null, 因为:需要走到链表最后一位;
赋值:使用cur.next=l1; 因为:cur的初始化为dummy,而dummy.next 是L3的头部;
--------------------------------------------------------------------------------------------------------------------
3 环的长度
给出一个单向链表的头指针,如果有环,则返回环的长度,否则返回零;
思路1(c++):
http://www.cnblogs.com/xudong-bupt/p/3667729.html
思路2(java):
http://www.cnblogs.com/smyhvae/p/4782595.html
slow和fast两个指针扫描链表,slow每次走1步,fast每次走2步;
1 判断是否有环?
如果有环 ,slow和fast相遇;返回相遇点;
如果无环,fast会遇到null;返回null;
linked list cycle1:https://leetcode.com/problems/linked-list-cycle/
linked list cycle2: https://leetcode.com/problems/linked-list-cycle-ii/
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public Node hasCycle(Node head) { if(head == null) return null; Node slow=head; Node fast=head; while(fast != null && fast.next!=null && fast.next.next!=null) { //注意:先增,后比较相等;否则,首次指向head,一定会相等; slow=slow.next; fast=fast.next.next; if(slow==fast) return slow; } return null; }
2 判断环长
slow和fast 首次相遇,记为pos; 下次相遇时,记为Join; pos->join,令slow走了len; fast走了2len; 环长为len;需要记忆,快慢指针两次相遇,长度为length;
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19//node指的是首次相遇节点 public int GetCycleLength(Node node) { if(node=null)//边界条件 return 0; Node slow = node; Node fast= node; length=0; while(fast!=null&&fast.next.next!=null) { slow=slow.next fast=fast.next.next; length++; if(slow==fast) return length; } return length; }
最后
以上就是呆萌世界最近收集整理的关于LinkedList 合并、环的长度、翻转等问题的全部内容,更多相关LinkedList内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复