做LeetCode碰到兩個快慢指針運用的題目,記錄一下,當然這個東西應用的地方肯定不止下面這兩個了,以后要是碰到就再更新
快慢指針:
這里快慢實際是指他們移動的步數,一個一次移動多個位置(一般二),一個移動一個
1,判斷鏈表里是否存在環
題目描述:
給定一個鏈表,判斷鏈表中是否有環。
為了表示給定鏈表中的環,我們使用整數
pos
來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果pos
是-1
,則在該鏈表中沒有環。
思路:快指針和慢指針同時往鏈表后面移動,如果快指針到達NULL,說明鏈表以NULL為結尾,沒有環。如果快指針追上慢指針(即兩個相等),則表示有環。
代碼:

/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public boolean hasCycle(ListNode head) { if (head==null) { return false; } ListNode slow = head; ListNode fast = head; while(fast!=null&&fast.next!=null) { slow = slow.next; fast = fast.next.next; if (fast==slow) { return true; } } return false; } }
二,一個排序鏈表里找到中位數
這里其實就是倍數關系了,假設把快慢指針比作一條道路上的車,快車的速度是慢車的兩倍,同時出發,那么快車到達終點的時候慢車就在這條路的中間位置!
但是到鏈表里就得注意元素個數奇偶的問題,奇數直接返回slow,偶數的話,返回slow和slow下一個數的和除2
代碼:

package com.mine.leetcode; import java.util.List; public class Solution141 { public int getMidElement(ListNode head) { ListNode fast = head; ListNode slow = head; while(fast!=null&&slow!=null) { //System.out.println("-"+fast.val); if(fast.next==null) return slow.val; else if(fast.next!=null&&fast.next.next==null) return (slow.val+slow.next.val)/2; else { fast = fast.next.next; slow = slow.next; } } return 666; } public static ListNode generateListByArray(int[] nums) { ListNode head = new ListNode(0); ListNode temp = head; for(int i = 0;i < nums.length;i++) { temp.next = new ListNode(nums[i]); temp = temp.next; } return head.next; } public static void main(String[] args) { int[] nums = {1,2,3,4,5,6,7}; System.out.println(new Solution141().getMidElement(generateListByArray(nums))); } }
三,輸出鏈表的倒數第K個節點
也是跟上面差不多的原理,第一個指針從鏈表的頭指針開始遍歷向前走k-1步,第二個指針保持不動;從第K步開始,第二個指針也開始從鏈表的頭指針開始遍歷。由於兩個指針的距離保持在k-1,當第一個指針到達鏈表的尾節點時候,第二個指針正好是倒數第K個節點
代碼:

package com.mine.leetcode; import java.util.List; public class Solution141 { // 查找單鏈表中倒數第K個結點 public ListNode GetKthNode(ListNode pHead, int k) // 函數名前面的R代表反向 { if(k == 0 || pHead == null) // 這里k的計數是從1開始的,若k為0或鏈表為空返回NULL return null; ListNode pAhead = pHead; ListNode pBehind = pHead; for(int i=0;i<k-1;i++){ pAhead=pAhead.next; if(pAhead==null) return null;//當鏈表長度小於k時候,返回Null } while(pAhead.next != null) // 前后兩個指針一起向前走,直到前面的指針指向最后一個結點 { pBehind = pBehind.next; pAhead = pAhead.next; } return pBehind; // 后面的指針所指結點就是倒數第k個結點 } public static void main(String[] args) { int[] nums = {1,2,3,4,5,6,7}; System.out.println(new Solution141().GetKthNode(generateListByArray(nums), 2).val); } }