Demo

 1 package LeetCode.test9_lianbiao;
 2 
 3 public class ListNode {
 4     int val;
 5     ListNode next;
 6 
 7     public ListNode() {
 8 
 9     }
10 
11     public ListNode(int val) {
12         this.val = val;
13     }
14 
15     public ListNode(int val, ListNode next) {
16         this.val = val;
17         this.next = next;
18     }
19 }

1、反转链表

问题:

你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:

输入:head = [1,2]
输出:[2,1]
示例 3:

输入:head = []
输出:[]

 1 package LeetCode.test9_lianbiao;
 2 
 3 /**
 4  * 思路1:先对原链表做头删操作,再对新链表做头插
 5  * 思路2:  _  1->2->3    _ <-1  2->3   _ <-1  2->3    _ <-1 <-2  3   _ <-1 <-2  3       _ <-1 <-2 <-3
 6  *        p0 p1 p2       p0 p1 p2      p0 p1 p2           p0 p1 p2      p0  p1  p2              p0  p1  p2   p2=null
 7  *                          p0 p1         p0 p1 p2           p0 p1          p0  p1  p2              p0  p1   p1=null
 8  */
 9 public class ques_206_反转链表 {
10     public ListNode reverseList(ListNode head) {
11         ListNode newHead = null;  // 定义一个新的头结点
12         ListNode node;   //定义一个临时中转站
13         while (head != null) {
14             //对之前的链表做头删
15             node = head;
16             head = head.next;
17             //对新链表做头插 (eg:1234)
18             node.next = newHead;
19             // node(1)->newHead(null) node(2)->newHead(1) node(3)->newHead(2)->(1)  node(4)->newHead(3)->(1)->(1)
20             newHead = node;
21             // newHead(1)       newHead(2)    newHead(3)   newHead(4)
22         }
23         return newHead;
24     }
25 
26     public ListNode reverseList2(ListNode head) {
27         ListNode p0 = null;
28         ListNode p1 = head;
29         ListNode p2 = head.next;
30         while (p1 != null) {
31             p1.next = p0;
32             p0 = p1;
33             p1 = p2;
34             if (p2 != null) {
35                 p2 = p2.next;
36             }
37         }
38         return p0;
39     }
40 }
41 
42 class Test_206 {
43     public static void main(String[] args) {
44         int[] head = {1, 2};
45         int index = 0;
46         ListNode listNode = create(head, index);
47 //        PreOrder(listNode);
48         ques_206_反转链表 s = new ques_206_反转链表();
49 //        PreOrder(s.reverseList(listNode));
50         PreOrder(s.reverseList2(listNode));
51     }
52 
53     private static ListNode create(int[] head, int index) {
54         ListNode listNode;
55         if (index >= head.length) {
56             return null;
57         }
58         listNode = new ListNode(head[index]);
59         listNode.next = create(head, index + 1);
60         return listNode;
61     }
62 
63     private static void PreOrder(ListNode listNode) {
64         if (listNode == null) {
65             return;
66         }
67         System.out.print(listNode.val + " ");
68         PreOrder(listNode.next);
69     }
70 }
View Code

2、合并两个有序链表

问题:

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:

输入:l1 = [], l2 = []
输出:[]
示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

 1 package LeetCode.test9_lianbiao;
 2 
 3 public class ques_21_合并两个有序链表 {
 4     public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
 5         ListNode newHead = new ListNode(0);
 6         ListNode node = newHead; // 指针
 7         while (list1 != null && list2 != null) {
 8             if (list1.val <= list2.val) {
 9                 node.next = list1;
10                 list1 = list1.next;
11             } else {
12                 node.next = list2;
13                 list2 = list2.next;
14             }
15             node = node.next;
16         }
17         if (node.next == list1) {  //list1循环完了,把list2加在后面。
18             node.next = list2;
19         } else { //list2循环完了,把list1加在后面。
20             node.next = list1;
21         }
22         return newHead.next;
23     }
24 }
25 
26 class Test_21 {
27     public static void main(String[] args) {
28         int[] head1 = {1, 2, 4};
29         int[] head2 = {1, 3, 4};
30         int index = 0;
31         ListNode list1 = create(head1, index);
32         ListNode list2 = create(head2, index);
33         ques_21_合并两个有序链表 s = new ques_21_合并两个有序链表();
34         PreOrder(s.mergeTwoLists(list1, list2));
35     }
36 
37     private static ListNode create(int[] head, int index) {
38         ListNode listNode;
39         if (index >= head.length) {
40             return null;
41         }
42         listNode = new ListNode(head[index]);
43         listNode.next = create(head, index + 1);
44         return listNode;
45     }
46 
47     private static void PreOrder(ListNode listNode) {
48         if (listNode == null) {
49             return;
50         }
51         System.out.print(listNode.val + " ");
52         PreOrder(listNode.next);
53     }
54 }
View Code

3、两两交换链表中的节点

问题:

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例 1:

输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:

输入:head = []
输出:[]
示例 3:

输入:head = [1]
输出:[1]

 1 package LeetCode.test9_lianbiao;
 2 
 3 /**
 4  * 思路:
 5  * 1-> 2 -> 3 -> 4     1 <- 2    3 -> 4       1 <- 2    3 <- 4                       null <- 3 <- 4
 6  * one two three       one two three                    one two three(head)=null     null <- 3 <- 4 <- 1 <- 2(two)
 7  */
 8 public class ques_24_两两交换链表中的节点 {
 9     public ListNode swapPairs(ListNode head) {
10         if (head == null || head.next == null) {
11             return head;
12         }
13         ListNode one = head;
14         ListNode two = one.next;
15         ListNode three = two.next;
16 
17         two.next = one;
18         one.next = swapPairs(three);
19 
20         return two;
21     }
22 }
23 
24 class Test_24 {
25     public static void main(String[] args) {
26         int[] root = {1, 2, 3, 4};
27         int index = 0;
28         ListNode head = create(root, index);
29         ques_24_两两交换链表中的节点 s = new ques_24_两两交换链表中的节点();
30         PreOrder(s.swapPairs(head));
31     }
32 
33     private static ListNode create(int[] head, int index) {
34         ListNode listNode;
35         if (index >= head.length) {
36             return null;
37         }
38         listNode = new ListNode(head[index]);
39         listNode.next = create(head, index + 1);
40         return listNode;
41     }
42 
43     private static void PreOrder(ListNode listNode) {
44         if (listNode == null) {
45             return;
46         }
47         System.out.print(listNode.val + " ");
48         PreOrder(listNode.next);
49     }
50 }
View Code

4、相交链表

问题:

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

自定义评测:

评测系统 的输入如下(你设计的程序不适用此输入):

intersectVal - 相交的起始节点的值。如果不存在相交节点,这一值为 0
listA - 第一个链表
listB - 第二个链表
skipA - 在 listA 中(从头节点开始)跳到交叉节点的节点数
skipB - 在 listB 中(从头节点开始)跳到交叉节点的节点数
评测系统将根据这些输入创建链式数据结构,并将两个头节点 headA 和 headB 传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案 。

示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例 2:

输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at '2'
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [1,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
示例 3:

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。

 1 package LeetCode.test9_lianbiao;
 2 
 3 /**
 4  * 思路:使用双指针法。
 5  * 假设链表A的头节点到相交点的距离是a,链表B的头节点到相交点的距离是b,相交点到链表终点的距离为c。我们使用两个指针,分别指向两个链表的头节点,
 6  * 并以相同的速度前进,若到达链表结尾,则移动到另一条链表的头节点继续前进。按照这种前进方法,两个指针会在a+b+c次前进后同时到达相交节点。
 7  */
 8 public class ques_160_相交链表 {
 9     public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
10         if (headA == null || headB == null) {
11             return null;
12         }
13         ListNode lA = headA;
14         ListNode lB = headB;
15         while (lA != lB) {
16             lA = (lA != null ? lA.next : headB);
17             lB = (lB != null ? lB.next : headA);
18         }
19         return lA;
20     }
21 }
22 
23 class Test_160 {
24     public static void main(String[] args) {
25         int[] listA = {4, 1, 8, 4, 5};
26         int[] listB = {5, 6, 1, 8, 4, 5};
27     }
28 }
View Code

5、回文链表

问题:

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

示例 1:

输入:head = [1,2,2,1]
输出:true
示例 2:

输入:head = [1,2]
输出:false

 1 package LeetCode.test9_lianbiao;
 2 
 3 /**
 4  * 链表中快慢指针的妙用:
 5  * 1、找中间值:把一个链表看成一个跑道,假设a的速度是b的两倍,那么当a跑完全程后,b刚好跑一半,以此来达到找到中间节点的目的。
 6  * 2、判断链表中的环
 7  * 3、删除倒数第n个:删除倒数第n个节点,那就等于要先找出待删除元素前一个元素,也就是第n-1个节点。一开始就让fast指针比slow指针快n+1个元素,
 8  * 接下来,两个指针都是一步一步来往下走。那么当fast指针走完时,slow指针就刚刚好停留在第(n-1)个元素上。
 9  * 思路:先使用快慢指针找到链表中点,再把链表切成两半;然后把后半段翻转;最后比较两半是否相等。
10  */
11 public class ques_234_回文链表 {
12     public boolean isPalindrome(ListNode head) {
13         if (head == null) {
14             return false;
15         } else if (head.next == null) {
16             return true;
17         } else if (head.next.next == null) {
18             if (head.val == head.next.val) {
19                 return true;
20             } else {
21                 return false;
22             }
23         }
24         ListNode fast = head;
25         ListNode slow = head;
26         while (fast.next != null && fast.next.next != null) {
27             fast = fast.next.next;
28             slow = slow.next;
29         }
30         ListNode newHead = slow.next;  // [2 1]  -> [1 2]
31 
32         ListNode afterHead = null;  // 定义一个新的头结点
33         ListNode node;   //定义一个临时中转站
34         while (newHead != null) {
35             //对之前的链表做头删
36             node = newHead;
37             newHead = newHead.next;
38             //对新链表做头插
39             node.next = afterHead;
40             afterHead = node;
41         }
42         ListNode beforeHead = head;
43         while (afterHead != null) {
44             if (afterHead.val != beforeHead.val) {
45                 return false;
46             }
47             afterHead = afterHead.next;
48             beforeHead = beforeHead.next;
49         }
50         return true;
51     }
52 }
53 
54 class Test_234 {
55     public static void main(String[] args) {
56 //        int[] head = {1, 2, 3, 2, 1};
57 //        int[] head = {1, 2, 2, 1};
58 //        int[] head = {1, 2};
59 //        int[] head = {1};
60         int[] head = {1, 1, 2, 1};
61         int index = 0;
62         ListNode list = create(head, index);
63 //        PreOrder(list);
64         ques_234_回文链表 s = new ques_234_回文链表();
65         System.out.println(s.isPalindrome(list));
66 
67     }
68 
69     private static ListNode create(int[] head, int index) {
70         ListNode listNode;
71         if (index >= head.length) {
72             return null;
73         }
74         listNode = new ListNode(head[index]);
75         listNode.next = create(head, index + 1);
76         return listNode;
77     }
78 
79     private static void PreOrder(ListNode listNode) {
80         if (listNode == null) {
81             return;
82         }
83         System.out.print(listNode.val + " ");
84         PreOrder(listNode.next);
85     }
86 }
View Code

6、删除排序链表中的重复元素

问题:

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

示例 1:

输入:head = [1,1,2]
输出:[1,2]
示例 2:

输入:head = [1,1,2,3,3]
输出:[1,2,3]

 1 package LeetCode.test9_lianbiao;
 2 
 3 public class ques_83_删除排序链表中的重复元素 {
 4     public ListNode deleteDuplicates(ListNode head) {
 5         if (head == null) {
 6             return null;
 7         }
 8         ListNode preNode = head;
 9         ListNode curNode = head.next;
10         ListNode node;
11         while (curNode != null) {
12             if (preNode.val == curNode.val) {
13                 if (curNode.next != null) {
14                     node = curNode.next;
15                     preNode.next = node;
16                     curNode = node;
17                 } else {
18                     preNode.next = null;
19                     curNode = null;
20                 }
21 
22             } else {
23                 preNode = curNode;
24                 curNode = curNode.next;
25             }
26         }
27 //        PreOrder(head);
28         return head;
29     }
30 
31     // 测试
32     private static void PreOrder(ListNode listNode) {
33         if (listNode == null) {
34             return;
35         }
36         System.out.print(listNode.val + " ");
37         PreOrder(listNode.next);
38     }
39 }
40 
41 class Test_83 {
42     public static void main(String[] args) {
43 //        int[] head = {1};
44 //        int[] head = {1, 1};
45 //        int[] head = {1, 2};
46 //        int[] head = {1, 1, 2};
47         int[] head = {1, 1, 2, 2};
48         int index = 0;
49         ListNode list = create(head, index);
50         ques_83_删除排序链表中的重复元素 s = new ques_83_删除排序链表中的重复元素();
51         System.out.println(s.deleteDuplicates(list));
52 
53     }
54 
55     private static ListNode create(int[] head, int index) {
56         ListNode listNode;
57         if (index >= head.length) {
58             return null;
59         }
60         listNode = new ListNode(head[index]);
61         listNode.next = create(head, index + 1);
62         return listNode;
63     }
64 }
View Code

补:

问题:删除有序链表中重复的元素-II

 

给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。

示例 1:

输入:{1,2,2}
输出:{1}
示例 2:

输入:{}
输出:{}

 1 import java.util.*;
 2 
 3 public class Solution {
 4     public ListNode deleteDuplicates (ListNode head) {
 5         if(head==null){
 6             return null;
 7         }
 8         
 9         ListNode temp = new ListNode(-1);
10         ListNode res = temp;
11         temp.next = head;
12         
13         ListNode preNode = head;
14         ListNode curNode = head.next;
15         ListNode node = null;
16         while(curNode!=null){
17             if(preNode.val==curNode.val){
18                 if(curNode.next!=null){
19                     if(preNode.val==curNode.next.val){
20                         curNode = curNode.next;
21                     }else{
22                         node = curNode.next;
23                         temp.next = node;
24                         preNode = node;
25                         curNode = node.next;
26                     }
27                 }else{
28                     temp.next = null;
29                     preNode = null;
30                     curNode = null; // 终止条件
31                 } 
32             }else{
33                 temp = temp.next;
34                 preNode = preNode.next;
35                 curNode = curNode.next;
36             }
37         }
38         return res.next;  
39     }
40 }
View Code

7、奇偶链表

问题:

给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。

第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。

请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。

你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。

示例 1:

输入: head = [1,2,3,4,5]
输出: [1,3,5,2,4]
示例 2:

输入: head = [2,1,3,5,6,4,7]
输出: [2,3,6,7,1,5,4]

 1 package LeetCode.test9_lianbiao;
 2 
 3 public class ques_328_奇偶链表 {
 4     public ListNode oddEvenList(ListNode head) {
 5         if (head == null) {
 6             return null;
 7         } else if (head.next == null) {
 8             return head;
 9         }
10         ListNode preNode = head;
11         ListNode curNode = head.next;
12         ListNode node;
13         ListNode newHead = new ListNode(-1);
14         ListNode newNode = newHead;
15 
16         while (curNode != null) {
17             // 接在新链表下
18             newNode.next = curNode;
19             newNode = curNode;
20 
21             node = curNode.next;
22             if (node != null) {
23                 preNode.next = node;
24                 preNode = node;
25                 if (node.next != null) {
26                     curNode = node.next;
27                 } else {
28                     curNode = null;
29                     // 此时删除新链表最后一个节点
30                     newNode.next = null;
31                 }
32 
33             } else {
34                 preNode.next = null;
35                 curNode = null;
36             }
37         }
38         preNode.next = newHead.next;
39 //        PreOrder(head);
40         return head;
41     }
42 
43     // 测试
44     private static void PreOrder(ListNode listNode) {
45         if (listNode == null) {
46             return;
47         }
48         System.out.print(listNode.val + " ");
49         PreOrder(listNode.next);
50     }
51 }
52 
53 class Test_328 {
54     public static void main(String[] args) {
55         int[] head = {1, 2, 3, 4, 5, 6};
56 //        int[] head = {1, 2, 3, 4, 5};
57 //        int[] head = {1};
58         int index = 0;
59         ListNode list = create(head, index);
60         ques_328_奇偶链表 s = new ques_328_奇偶链表();
61         System.out.println(s.oddEvenList(list));
62 
63     }
64 
65     private static ListNode create(int[] head, int index) {
66         ListNode listNode;
67         if (index >= head.length) {
68             return null;
69         }
70         listNode = new ListNode(head[index]);
71         listNode.next = create(head, index + 1);
72         return listNode;
73     }
74 }
View Code
 1 import java.util.*;
 2 
 3 public class Solution {
 4     public ListNode oddEvenList (ListNode head) {
 5         if(head==null){
 6             return null;
 7         }
 8         ListNode fastHead = head.next;
 9         ListNode lowtail = head;
10         ListNode fasttail = fastHead;
11         while(fasttail!=null&&fasttail.next!=null){
12             lowtail.next = fasttail.next;
13             lowtail = lowtail.next;
14             fasttail.next = lowtail.next;
15             fasttail = fasttail.next;
16         }
17         lowtail.next = fastHead;
18         return head;
19     }
20 }
View Code

8、删除链表的倒数第N个结点

问题:

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:

输入:head = [1], n = 1
输出:[]
示例 3:

输入:head = [1,2], n = 1
输出:[1]

 1 package LeetCode.test9_lianbiao;
 2 
 3 public class ques_19_删除链表的倒数第N个结点 {
 4     public ListNode removeNthFromEnd(ListNode head, int n) {
 5         ListNode temp = new ListNode(-1);
 6         temp.next = head;
 7         ListNode slow = temp;
 8         ListNode fast = temp;
 9         while (n != 0) {
10             fast = fast.next;
11             n--;
12         }
13         while (fast.next != null) {
14             slow = slow.next;
15             fast = fast.next;
16         }
17         ListNode node = slow.next.next;
18         if (node != null) {
19             slow.next = node;
20         } else {
21             slow.next = null;
22         }
23 //        PreOrder(temp.next);
24         return temp.next;
25     }
26 
27     private static void PreOrder(ListNode listNode) {
28         if (listNode == null) {
29             return;
30         }
31         System.out.print(listNode.val + " ");
32         PreOrder(listNode.next);
33     }
34 }
35 
36 class Test_19 {
37     public static void main(String[] args) {
38         int[] head = {1, 2, 3, 4, 5, 6, 7, 8};
39         int n = 3;
40 //        int[] head = {1,2};
41 //        int n = 2;
42 //        int[] head = {1};
43 //        int n = 1;
44         int index = 0;
45         ListNode list = create(head, index);
46         ques_19_删除链表的倒数第N个结点 s = new ques_19_删除链表的倒数第N个结点();
47         System.out.println(s.removeNthFromEnd(list, n));
48 
49     }
50 
51     private static ListNode create(int[] head, int index) {
52         ListNode listNode;
53         if (index >= head.length) {
54             return null;
55         }
56         listNode = new ListNode(head[index]);
57         listNode.next = create(head, index + 1);
58         return listNode;
59     }
60 }
View Code

9、排序链表

问题:

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

示例 1:

输入:head = [4,2,1,3]
输出:[1,2,3,4]
示例 2:

输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
示例 3:

输入:head = []
输出:[]

 1 package LeetCode.test9_lianbiao;
 2 
 3 /**
 4  * 利用快慢指针找到链表中点后,可以对链表进行归并排序。
 5  */
 6 public class ques_148_排序链表 {
 7     public ListNode sortList(ListNode head) {
 8         PreOrder(merge_sort(head));
 9         return merge_sort(head);
10     }
11 
12     public ListNode merge_sort(ListNode head) {
13         if (head == null) {
14             return head;
15         }
16         if (head.next == null) {  // 递归终止条件
17             return head;
18         }
19         ListNode slow = head;
20         ListNode fast = head;
21         while (fast.next != null && fast.next.next != null) {
22             fast = fast.next.next;
23             slow = slow.next;
24         }
25         ListNode mid = slow;
26 
27         ListNode rightHead = mid.next;
28         mid.next = null;
29 
30         ListNode left = merge_sort(head);
31         ListNode right = merge_sort(rightHead);
32         return merge(left, right);
33     }
34 
35     public ListNode merge(ListNode left, ListNode right) {
36         ListNode node = new ListNode(-1);
37         ListNode temp = node;
38         ListNode temp1 = left;  // 2
39         ListNode temp2 = right; // 1
40         while (temp1 != null && temp2 != null) {
41             if (temp1.val < temp2.val) {
42                 temp.next = temp1;
43                 temp1 = temp1.next;
44             } else {
45                 temp.next = temp2;
46                 temp2 = temp2.next;
47             }
48             temp = temp.next; // 注意!!!
49         }
50         if (temp1 != null) {  // 2
51             temp.next = temp1;
52         }
53         if (temp2 != null) {
54             temp.next = temp2;
55         }
56         return node.next;
57     }
58 
59     private static void PreOrder(ListNode listNode) {
60         if (listNode == null) {
61             return;
62         }
63         System.out.print(listNode.val + " ");
64         PreOrder(listNode.next);
65     }
66 }
67 
68 class Test_148 {
69     public static void main(String[] args) {
70 //        int[] head = {4, 2, 1, 3};
71 //        int[] head = {4, 2, 1};
72 //        int[] head = {-1,5,3,4,0};
73         int[] head = {};
74         int index = 0;
75         ListNode list = create(head, index);
76         ques_148_排序链表 s = new ques_148_排序链表();
77         System.out.println(s.sortList(list));
78 
79     }
80 
81     private static ListNode create(int[] head, int index) {
82         ListNode listNode;
83         if (index >= head.length) {
84             return null;
85         }
86         listNode = new ListNode(head[index]);
87         listNode.next = create(head, index + 1);
88         return listNode;
89     }
90 }
View Code
 1 import java.util.*;
 2 
 3 public class Solution {
 4     public ListNode sortInList (ListNode head) {
 5         // write code here
 6         if(head==null||head.next==null){
 7             return head;
 8         }
 9         // 奇数个节点找到中点,偶数个节点找到中心左边的节点
10         ListNode fast = head.next; //!!!!!!!!!
11         ListNode slow = head;
12         while(fast!=null&&fast.next!=null){
13             fast = fast.next.next;
14             slow = slow.next;
15         }
16         ListNode mid = slow;
17         ListNode rightHead = mid.next;
18         mid.next = null;
19         
20         ListNode left = sortInList(head);
21         ListNode right = sortInList(rightHead);
22         
23         ListNode newHead = new ListNode(-1);
24         ListNode node = newHead;
25         while(left!=null&&right!=null){
26             if(left.val<right.val){
27                 node.next = left;
28                 left = left.next;
29             }else{
30                 node.next = right;
31                 right = right.next;
32                 
33             }
34             node = node.next;
35         }
36         if(left!=null){
37             node.next = left;
38         }
39         if(right!=null){
40             node.next = right;
41         }
42         return newHead.next;
43     }
44 }
View Code

10、链表内指定区间反转

问题:

将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n),空间复杂度 O(1)

示例 1:

输入:{1,2,3,4,5},2,4
输出:{1,4,3,2,5}
示例 2:

输入:{5},1,1
输出:{5}

 1 import java.util.*;
 2 
 3 public class Solution {
 4     public ListNode reverseBetween (ListNode head, int m, int n) {
 5         // write code here
 6         ListNode newHead = new ListNode(-1);
 7         newHead.next = head;
 8         
 9         ListNode preLeft = newHead;
10         for(int i = 0; i < m-1; i++){
11             preLeft = preLeft.next;
12         }
13         ListNode leftNode = preLeft.next;
14         
15         ListNode curRight = preLeft;
16         for(int i = 0; i< n-m+1; i++){
17             curRight = curRight.next;
18         }
19         ListNode rightNode = curRight;
20 
21         curRight = curRight.next;
22         
23         //截取
24         preLeft.next = null;
25         rightNode.next = null;
26         
27         //反转
28         ListNode newSonHead = reverseList(leftNode);
29         preLeft.next = newSonHead;
30         leftNode.next = curRight;
31         
32         return newHead.next;
33     }
34     
35     public ListNode reverseList(ListNode head){
36         ListNode newSonHead = null;
37         ListNode node = null;
38         while(head!=null){
39             node = head;
40             head = head.next;
41             node.next = newSonHead;
42             newSonHead = node;
43         }
44         return newSonHead;
45     }  
46 }
View Code

11、链表中的节点每k个一组翻转

问题:

将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。

示例 1:

输入:{1,2,3,4,5},2
输出:{2,1,4,3,5}
示例 2:

输入:{},1
输出:{}

 1 import java.util.*;
 2 
 3 public class Solution {
 4     public ListNode reverseKGroup (ListNode head, int k) {
 5         ListNode virtualHead = new ListNode(-1);
 6         ListNode result = virtualHead;
 7         Stack<ListNode> st = new Stack();
 8         
 9         while(true){
10             if(head==null){ // 取完链表或者空链表
11                 break;
12             }
13             for(int i=0;i<k;i++){
14                 st.add(head);
15                 head = head.next;
16                 if(head==null){ //少于k个退出for循环
17                     break;
18                 }
19             }
20             if(st.size()==k){
21                 while(!st.isEmpty()){
22                     virtualHead.next = st.pop();
23                     virtualHead = virtualHead.next;
24                 }
25             }
26         }
27         
28         ListNode endNode = null;
29         while(!st.isEmpty()){
30             endNode = st.pop();
31         }
32         virtualHead.next = endNode;
33         return result.next;
34     }
35 }
View Code

12、链表中环的入口结点

问题:

给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。

例如,输入{1,2},{3,4,5}时,对应的环形链表如下图所示:

 

 

 示例 1:

输入:{1,2},{3,4,5}
输出:3
示例 2:

输入:{1},{}
输出:"null"

示例 3:

输入:{},{2}

输出:2

 1 import java.util.*;
 2 
 3 public class Solution {
 4     public ListNode EntryNodeOfLoop(ListNode pHead) {
 5         ListNode fast = pHead;
 6         ListNode slow = pHead;
 7         while(fast!=null&&fast.next!=null){
 8             fast = fast.next.next;
 9             slow = slow.next;
10             if(fast == slow){            
11                 break;
12             }
13         }
14         if(fast == null||fast.next == null){
15             return null;
16         }
17         fast = pHead;
18         while(fast!=slow){
19             fast = fast.next;
20             slow = slow.next;
21         }
22         return fast;
23     }
24 }
View Code

 13、链表相加(二)

问题:

假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。
给定两个这种链表,请生成代表两个整数相加值的结果链表。

示例 1:

输入:[9,3,7],[6,3]
输出:{1,0,0,0}
示例 2:

输入:[0],[6,3]
输出:{6,3}

 1 import java.util.*;
 2 
 3 public class Solution {
 4     public ListNode addInList (ListNode head1, ListNode head2) {
 5         // write code here
 6         if(head1==null){
 7             return head2;
 8         }
 9         if(head2==null){
10             return head1;
11         }
12         Stack<ListNode> st1 = new Stack<>();
13         Stack<ListNode> st2 = new Stack<>();
14         while(head1!=null){
15             st1.add(head1);
16             head1 = head1.next;
17         }
18         while(head2!=null){
19             st2.add(head2);
20             head2 = head2.next;
21         }     
22         int tmp = 0; //进位
23         ListNode newHead = null;
24         //ListNode head = new ListNode(-1);
25         //ListNode newHead = head.next;
26         
27         while(!st1.isEmpty()||!st2.isEmpty()){
28             int num = tmp;
29             if(!st1.isEmpty()){
30                 num += st1.pop().val;
31             }
32             if(!st2.isEmpty()){
33                 num += st2.pop().val;
34             }
35             tmp = num / 10;
36             ListNode node = new ListNode(num%10);
37             node.next = newHead;
38             newHead = node;
39         }
40         if(tmp>0){
41             ListNode node = new ListNode(tmp);
42             node.next = newHead;
43             newHead = node;
44         }
45         return newHead; 
46     }
47 }
View Code

 

posted on 2022-03-12 17:14  晨曦生辉耀匕尖  阅读(50)  评论(0编辑  收藏  举报