mirror of
https://github.com/CyC2018/Interview-Notebook.git
synced 2026-10-27 22:13:45 +00:00
Update Leetcode 题解 - 双指针.md
补充三数之和、接雨水、最小覆盖子串,并配图说明接雨水的水位计算。
This commit is contained in:
@@ -8,6 +8,9 @@
|
||||
* [5. 归并两个有序数组](#5-归并两个有序数组)
|
||||
* [6. 判断链表是否存在环](#6-判断链表是否存在环)
|
||||
* [7. 最长子序列](#7-最长子序列)
|
||||
* [8. 三数之和](#8-三数之和)
|
||||
* [9. 接雨水](#9-接雨水)
|
||||
* [10. 最小覆盖子串](#10-最小覆盖子串)
|
||||
<!-- GFM-TOC -->
|
||||
|
||||
|
||||
@@ -290,3 +293,124 @@ private boolean isSubstr(String s, String target) {
|
||||
return j == target.length();
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 三数之和
|
||||
|
||||
15\. 3Sum (Medium)
|
||||
|
||||
[Leetcode](https://leetcode.com/problems/3sum/) / [力扣](https://leetcode.cn/problems/3sum/)
|
||||
|
||||
```text
|
||||
Input: nums = [-1, 0, 1, 2, -1, -4]
|
||||
Output: [[-1, -1, 2], [-1, 0, 1]]
|
||||
```
|
||||
|
||||
题目描述:找出所有和为 0 且不重复的三元组。
|
||||
|
||||
先排序,然后枚举第一个数 nums[i],在它右边用第 1 题的双指针方法寻找和为 -nums[i] 的两个数。去重的关键是跳过相同的值:i 跳过与前一个数相同的值,找到一组解之后,两个指针也跳过相同的值。时间复杂度为 O(N<sup>2</sup>)。
|
||||
|
||||
```java
|
||||
public List<List<Integer>> threeSum(int[] nums) {
|
||||
Arrays.sort(nums);
|
||||
List<List<Integer>> ret = new ArrayList<>();
|
||||
for (int i = 0; i < nums.length - 2; i++) {
|
||||
if (i > 0 && nums[i] == nums[i - 1]) {
|
||||
continue;
|
||||
}
|
||||
int l = i + 1, h = nums.length - 1;
|
||||
while (l < h) {
|
||||
int sum = nums[i] + nums[l] + nums[h];
|
||||
if (sum < 0) {
|
||||
l++;
|
||||
} else if (sum > 0) {
|
||||
h--;
|
||||
} else {
|
||||
ret.add(Arrays.asList(nums[i], nums[l], nums[h]));
|
||||
while (l < h && nums[l] == nums[l + 1]) {
|
||||
l++;
|
||||
}
|
||||
while (l < h && nums[h] == nums[h - 1]) {
|
||||
h--;
|
||||
}
|
||||
l++;
|
||||
h--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
|
||||
## 9. 接雨水
|
||||
|
||||
42\. Trapping Rain Water (Hard)
|
||||
|
||||
[Leetcode](https://leetcode.com/problems/trapping-rain-water/) / [力扣](https://leetcode.cn/problems/trapping-rain-water/)
|
||||
|
||||
```text
|
||||
Input: height = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]
|
||||
Output: 6
|
||||
```
|
||||
|
||||
位置 i 上方能存的水,取决于它左边最高的柱子和右边最高的柱子中较矮的那一个:water[i] = min(leftMax, rightMax) - height[i]。
|
||||
|
||||
用两个指针从两端向中间移动,分别维护 leftMax 和 rightMax。如果 leftMax < rightMax,左指针处的水位只由 leftMax 决定,因为右边已经有一根不低于 rightMax 的柱子,可以直接结算左指针并右移;反之结算右指针并左移。
|
||||
|
||||
<div align="center"> <img src="pics/trapping-rain-water.png" width="560px"/> </div><br>
|
||||
|
||||
```java
|
||||
public int trap(int[] height) {
|
||||
int l = 0, r = height.length - 1;
|
||||
int leftMax = 0, rightMax = 0, ret = 0;
|
||||
while (l < r) {
|
||||
leftMax = Math.max(leftMax, height[l]);
|
||||
rightMax = Math.max(rightMax, height[r]);
|
||||
if (leftMax < rightMax) {
|
||||
ret += leftMax - height[l++];
|
||||
} else {
|
||||
ret += rightMax - height[r--];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
|
||||
## 10. 最小覆盖子串
|
||||
|
||||
76\. Minimum Window Substring (Hard)
|
||||
|
||||
[Leetcode](https://leetcode.com/problems/minimum-window-substring/) / [力扣](https://leetcode.cn/problems/minimum-window-substring/)
|
||||
|
||||
```text
|
||||
Input: s = "ADOBECODEBANC", t = "ABC"
|
||||
Output: "BANC"
|
||||
```
|
||||
|
||||
题目描述:找出 s 中包含 t 所有字符(包括重复字符)的最短子串。
|
||||
|
||||
使用滑动窗口。need[c] 表示窗口还缺几个字符 c,missing 表示一共还缺几个字符。右指针不断扩大窗口,直到 missing 为 0,此时窗口包含了 t 的所有字符;然后移动左指针缩小窗口,在窗口仍然满足条件时更新答案。
|
||||
|
||||
```java
|
||||
public String minWindow(String s, String t) {
|
||||
int[] need = new int[128];
|
||||
for (char c : t.toCharArray()) {
|
||||
need[c]++;
|
||||
}
|
||||
int missing = t.length(), start = 0, minLen = Integer.MAX_VALUE;
|
||||
for (int l = 0, r = 0; r < s.length(); r++) {
|
||||
if (need[s.charAt(r)]-- > 0) {
|
||||
missing--;
|
||||
}
|
||||
while (missing == 0) {
|
||||
if (r - l + 1 < minLen) {
|
||||
minLen = r - l + 1;
|
||||
start = l;
|
||||
}
|
||||
if (++need[s.charAt(l++)] > 0) {
|
||||
missing++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return minLen == Integer.MAX_VALUE ? "" : s.substring(start, start + minLen);
|
||||
}
|
||||
```
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
Reference in New Issue
Block a user