Linked List Two Finish

(1)Remove Nth Node From End of List

解题思路:

题目要求只使用一次遍历。可以使用指针来完成单程解决方案。快速移动一个指针向前移动n + 1个位置,以保持两个指针之间的间隙,然后以相同的速度移动两个指针。

最后,当快速指针到达结束时,慢指针将在n + 1个位置后面 - 只是正确的点,以便能够跳过下一个节点。

代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) { val = x; }
 7  * }
 8  */
 9 public class Solution {
10     public ListNode removeNthFromEnd(ListNode head, int n) {
11         ListNode start = new ListNode(0);
12         ListNode fast = start, slow = start;
13         slow.next = head;
14         
15         for (int i = 1; i <= n+1; i++) {
16             fast = fast.next;
17         }
18         
19         while (fast != null) {
20             slow = slow.next;
21             fast = fast.next;
22         }
23         
24         slow.next = slow.next.next;
25         return start.next;
26     }
27 }
View Code

(2)Linked List Cycle

解题思路:

使用快慢引用的思路。两个引用都指向链表头,从链表头开始遍历,慢引用每次前进一步,而快引用每次前进两步,如果链表是有环路的,那么快引用终将追上慢引用;如果没有环路,那么遍历就会有结束的时候

代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) {
 7  *         val = x;
 8  *         next = null;
 9  *     }
10  * }
11  */
12 public class Solution {
13     public Boolean hasCycle(ListNode head) {
14         if (head == null) {
15             return false;
16         }
17 
18         ListNode fast, slow;
19         fast = head;
20         slow = head;
21         while (fast.next != null && fast.next.next != null) {
22             slow = slow.next;
23             fast = fast.next.next;
24             if(fast == slow) {
25                 return true;
26             }
27         } 
28         return false;
29     }
30 }
View Code

(3)Remove Linked List Elements

解题思路:简单明了,遍历整个链表,遇到相应值得节点删掉即可。

代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) { val = x; }
 7  * }
 8  */
 9 public class Solution {
10     public ListNode removeElements(ListNode head, int val) {
11         ListNode dummy = new ListNode(0);
12         dummy.next = head;
13         head = dummy;
14         while (head.next != null) {
15             if (head.next.val == val) {
16                 head.next = head.next.next;
17             } else {
18                 head = head.next;
19             }
20         }
21         return dummy.next;
22     }
23 }
View Code

(4)Intersection of Two Linked Lists

解题思路:

1,获取两个列表的长度。2,将它们对齐到相同的起点。3,将它们一起移动,直到找到交点,或者结束null

代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) {
 7  *         val = x;
 8  *         next = null;
 9  *     }
10  * }
11  */
12 public class Solution {
13     public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
14         int lenA = length(headA);
15         int lenB = length(headB);
16         // move headA and headB to the same start point
17         while (lenA > lenB) {
18             headA = headA.next;
19             lenA--;
20         }
21         while (lenA < lenB) {
22             headB = headB.next;
23             lenB--;
24         }
25         // find the intersection until end
26         while (headA != headB) {
27             headA = headA.next;
28             headB = headB.next;
29         }
30         return headA;
31         
32     }
33     private int length (ListNode node){
34         int length = 0;
35         while (node != null) {
36             node = node.next;
37             length++;
38         }
39         return length;
40     }
41 }
View Code

 (5)Palindrome Linked List

解题思路:

找到链表的中间节点,把后半段的原地链表反转(当然也可以反转前半段),然后和前半段进行比较,符合题目O(1)空间复杂度的要求。

代码如下:

 1 /**
 2  * Definition for singly-linked list.
 3  * public class ListNode {
 4  *     int val;
 5  *     ListNode next;
 6  *     ListNode(int x) { val = x; }
 7  * }
 8  */
 9 public class Solution {
10     public boolean isPalindrome(ListNode head) {
11          if (head == null || head.next == null) {//0个节点或是1个节点  
12              return true;  
13          }
14          //找到中间节点
15          ListNode fast = head; 
16          ListNode slow = head;  
17          while (fast.next != null && fast.next.next != null)  
18          {  
19              fast = fast.next.next;  
20              slow = slow.next;  
21          }  
22          //对链表后半段进行反转  
23          ListNode midNode = slow;  
24          ListNode firNode = slow.next;//后半段链表的第一个节点  
25          ListNode cur = firNode.next;//插入节点从第一个节点后面一个开始  
26          firNode.next = null;//第一个节点最后会变最后一个节点  
27          while (cur != null)  
28          {  
29              ListNode nextNode = cur.next;//保存下次遍历的节点  
30              cur.next = midNode.next;  
31              midNode.next = cur;  
32              cur = nextNode;  
33          }  
34            
35          //反转之后对前后半段进行比较  
36          fast = midNode.next;  
37          slow = head;  
38          while (fast != null)  
39          {  
40              if (fast.val != slow.val)  
41                  return false;  
42              slow = slow.next;  
43              fast = fast.next;  
44          }  
45          return true;
46     }
47 }
View Code
原文地址:https://www.cnblogs.com/struggleli/p/6193930.html