算法中的雙指針使用,有時候會以爲很巧妙,解決了不少的問題,有必要概括總結一下,首先雙指針也是個很寬泛的概念,它相似於遍歷中的 i 和 j
可是其區別是,兩個指針是同時移動的,即沒有貢獻複雜度從O(N)
到 O(N*N)
,因此被不少算法大佬所推崇,因此基於此概括總結出雙指針的常看法法和套路。算法
這裏將題型概括爲三種,分別以下:數組
前面講到,這三種指針都是遍歷一次數組便可完成,其時間複雜度低於或者等於O(N)
,空間複雜度是O(1)
由於就兩個指針存儲。大數據
至關經典的一道題:人工智能
經過步調不一致的兩個指針,一前一後一塊兒移動,直到指針重合了spa
https://leetcode.com/problems/linked-list-cycle/description,代碼片斷以下:指針
public boolean hasCycle(ListNode head) { ListNode slow = head; ListNode fast = head; while (slow != null && fast != null) { ListNode n = fast.next; fast = n == null ? null : n.next; if (slow == fast) { return true; } slow = slow.next; } return false; }
代碼解決以下:code
public int findDuplicate(int[] nums) { // 將其當作是一個循環的鏈表,快慢指針循環 int index1 = 0; int index2 = 0; do { index1 = nums[index1]; index2 = nums[index2]; index2 = nums[index2]; }while (nums[index1] != nums[index2]); index1 = 0; // 找出在哪一個位置爲起始點,可證一定在圓圈起點相遇 while(index1 != index2){ index1 = nums[index1]; index2 = nums[index2]; } return index1; }
二分查找是典型的先後指針的題型,代碼以下:ip
public static int binarySearch(int[] array, int targetElement) { int leftIndex = 0, rightIndex = array.length - 1, middleIndex = (leftIndex + rightIndex) / 2; while(leftIndex <= rightIndex) { int middleElement = array[middleIndex]; if(targetElement < middleElement) { rightIndex = middleIndex - 1; }else if(targetElement > middleElement) { leftIndex = middleIndex + 1; }else { return middleIndex; } middleIndex = (leftIndex + rightIndex) / 2; } return -1; }
// 快指針q每次走2步,慢指針p每次走1步,當q走到末尾時p正好走到中間。 class Solution { public ListNode middleNode(ListNode head) { ListNode p = head, q = head; while (q != null && q.next != null) { q = q.next.next; p = p.next; } return p; } }
// 快慢指針,先讓快指針走k步,而後兩個指針同步走,當快指針走到頭時,慢指針就是鏈表倒數第k個節點。 public ListNode getKthFromEnd(ListNode head, int k) { ListNode frontNode = head, behindNode = head; while (frontNode != null && k > 0) { frontNode = frontNode.next; k--; } while (frontNode != null) { frontNode = frontNode.next; behindNode = behindNode.next; } return behindNode; }
看完三個代碼,是否是以爲很簡單,下面總結一下三種雙指針的代碼模板leetcode
// 1.快慢指針 l = 0 r = 0 while 沒有遍歷完 if 必定條件 l += 1 r += 1 return 合適的值 //2. 左右端點指針 l = 0 r = n - 1 while l < r if 找到了 return 找到的值 if 必定條件1 l += 1 else if 必定條件2 r -= 1 return 沒找到 //3. 固定間距指針 l = 0 r = k while 沒有遍歷完 自定義邏輯 l += 1 r += 1 return 合適的值
吳邪,小三爺,混跡於後臺,大數據,人工智能領域的小菜鳥。
更多請關注get