一、快慢指针
原地修改
LeetCode 26. 删除有序数组中的重复项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public int removeDuplicates(int[] nums) { if (nums.length == 0) { return 0; } int slow = 0, fast = 0; while (fast < nums.length) { if (nums[fast] != nums[slow]) { slow++; nums[slow] = nums[fast]; } fast++; } return slow + 1; } }
|
LeetCode 27.移除元素
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Solution { public int removeElement(int[] nums, int val) { int fast = 0, slow = 0; while (fast < nums.length) { if (nums[fast] != val) { nums[slow] = nums[fast]; slow++; } fast++; } return slow; } }
|
与26题存在差别:先给 nums[slow] 赋值然后再给 slow++,这样可以保证 nums[0..slow-1] 是不包含值为 val 的元素的,最后的结果数组长度就是 slow。
LeetCode 283.移动零
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Solution { public void moveZeroes(int[] nums) { int p = removeElement(nums, 0); for (; p < nums.length; p++) { nums[p] = 0; } }
public int removeElement(int[] nums, int val) { } }
|
滑动窗口
滑动窗口代码框架:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| int left = 0, right = 0;
while (right < nums.size()) { window.addLast(nums[right]); right++; while (window needs shrink) { window.removeFirst(nums[left]); left++; } }
|
二、左右指针
二分方法下左右指针:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| int binarySearch(int[] nums, int target) { int left = 0, right = nums.length - 1; while(left <= right) { int mid = (right + left) / 2; if(nums[mid] == target) return mid; else if (nums[mid] < target) left = mid + 1; else if (nums[mid] > target) right = mid - 1; } return -1; }
|
LeetCode 167.两数之和Ⅱ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public int[] twoSum(int[] numbers, int target) { int left = 0, right = numbers.length - 1; while (left < right) { int sum = numbers[left] + numbers[right]; if (sum == target) { return new int[]{left + 1, right + 1}; } else if (sum < target) { left++; } else if (sum > target) { right--; } } return new int[]{-1, -1}; } }
|
Leetcode 344.反转字符串
1 2 3 4 5 6 7 8 9 10 11 12
| void reverseString(char[] s) { int left = 0, right = s.length - 1; while (left < right) { char temp = s[left]; s[left] = s[right]; s[right] = temp; left++; right--; } }
|
Leetcode 5.最长回文子串
判断回文串:
1 2 3 4 5 6 7 8 9 10 11 12
| boolean isPalindrome(String s) { int left = 0, right = s.length() - 1; while (left < right) { if (s.charAt(left) != s.charAt(right)) { return false; } left++; right--; } return true; }
|
找回文串关键点在于,回文串长度可能为奇数也可能是偶数,解决问题核心在于从回文串中心向两边扩散的双指针技巧。
如果回文串长度为奇数,则它有一个中心字符;如果回文串长度为偶数,则有两个中心字符。
函数实现:
1 2 3 4 5 6 7 8 9 10 11
| String palindrome(String s, int l, int r) { while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { l--; r++; } return s.substring(l + 1, r); }
|
整体解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| String longestPalindrome(String s) { String res = ""; for (int i = 0; i < s.length(); i++) { String s1 = palindrome(s, i, i); String s2 = palindrome(s, i, i + 1); res = res.length() > s1.length() ? res : s1; res = res.length() > s2.length() ? res : s2; } return res; } String palindrome(String s, int l, int r) { while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) { l--; r++; } return s.substring(l + 1, r); }
|