6.11 二刷hot100 哈希+双指针
This commit is contained in:
parent
a26333688a
commit
d3cfe89d74
@ -25,6 +25,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//做出来了。
|
//做出来了。
|
||||||
|
//二刷会做
|
||||||
public class GroupAnagrams {
|
public class GroupAnagrams {
|
||||||
//计数
|
//计数
|
||||||
public List<List<String>> groupAnagrams1(String[] strs) {
|
public List<List<String>> groupAnagrams1(String[] strs) {
|
||||||
|
@ -23,6 +23,7 @@ import java.util.HashSet;
|
|||||||
输出:3
|
输出:3
|
||||||
*/
|
*/
|
||||||
//没做出来
|
//没做出来
|
||||||
|
//二刷会做
|
||||||
public class LongestConsecutive {
|
public class LongestConsecutive {
|
||||||
public int longestConsecutive(int[] nums) {
|
public int longestConsecutive(int[] nums) {
|
||||||
// 将数组中的所有元素存入 HashSet
|
// 将数组中的所有元素存入 HashSet
|
||||||
|
@ -15,8 +15,9 @@ import java.util.LinkedList;
|
|||||||
* 链接:https://leetcode.cn/problems/trapping-rain-water/
|
* 链接:https://leetcode.cn/problems/trapping-rain-water/
|
||||||
*/
|
*/
|
||||||
//困难题 不会
|
//困难题 不会
|
||||||
|
//二刷不会
|
||||||
public class Trap {
|
public class Trap {
|
||||||
//暴力解法
|
//暴力解法 竖着收集雨水
|
||||||
public int trap1(int[] height) {
|
public int trap1(int[] height) {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for (int i = 0; i < height.length; i++) {
|
for (int i = 0; i < height.length; i++) {
|
||||||
@ -24,21 +25,35 @@ public class Trap {
|
|||||||
if (i == 0 || i == height.length - 1) {
|
if (i == 0 || i == height.length - 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 目的:对于每一个柱子 i,想知道它“左右两边的最高柱子”分别是多少。
|
||||||
|
*
|
||||||
|
* 因为要接雨水,关键在于“当前位置能接多少水”取决于:
|
||||||
|
*
|
||||||
|
* 它左边的最高柱子
|
||||||
|
* 它右边的最高柱子
|
||||||
|
* 当前柱子的高度
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int rHeight = height[i]; // 初始化右边最大高度为当前位置高度(后面会尝试找更高的)
|
||||||
|
int lHeight = height[i]; // 初始化左边最大高度为当前位置高度(后面会尝试找更高的)
|
||||||
|
|
||||||
int rHeight = height[i]; // 记录右边柱子的最高高度
|
// 从当前位置 i 向右扫描,找出右侧最高的柱子高度
|
||||||
int lHeight = height[i]; // 记录左边柱子的最高高度
|
|
||||||
|
|
||||||
for (int r = i + 1; r < height.length; r++) {
|
for (int r = i + 1; r < height.length; r++) {
|
||||||
if (height[r] > rHeight) {
|
if (height[r] > rHeight) {
|
||||||
rHeight = height[r];
|
rHeight = height[r]; // 更新右侧最高高度
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 从当前位置 i 向左扫描,找出左侧最高的柱子高度
|
||||||
for (int l = i - 1; l >= 0; l--) {
|
for (int l = i - 1; l >= 0; l--) {
|
||||||
if (height[l] > lHeight) {
|
if (height[l] > lHeight) {
|
||||||
lHeight = height[l];
|
lHeight = height[l]; // 更新左侧最高高度
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int h = Math.min(lHeight, rHeight) - height[i];
|
int h = Math.min(lHeight, rHeight) - height[i];
|
||||||
if (h > 0) {
|
if (h > 0) {
|
||||||
sum += h;
|
sum += h;
|
||||||
@ -46,7 +61,19 @@ public class Trap {
|
|||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
//动态规划
|
//动态规划 竖着收集雨水
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对于每一个柱子 i,接雨水的能力取决于它左右两边最高柱子的最小值。
|
||||||
|
* 因此,预先构造两个数组:
|
||||||
|
* maxLeft[i] 表示从左到 i 的最大值
|
||||||
|
* maxRight[i] 表示从右到 i 的最大值
|
||||||
|
* 然后遍历每一个柱子(除了两端),计算:
|
||||||
|
* Math.min(maxLeft[i - 1], maxRight[i + 1]) - height[i]
|
||||||
|
*
|
||||||
|
* @param height
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public int trap2(int[] height) {
|
public int trap2(int[] height) {
|
||||||
if (height.length <= 2) return 0;
|
if (height.length <= 2) return 0;
|
||||||
int n = height.length;
|
int n = height.length;
|
||||||
@ -76,7 +103,54 @@ public class Trap {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
//单调栈
|
//双指针 竖着收集雨水
|
||||||
|
/**
|
||||||
|
* 左右各有一个指针,从两端向中间走
|
||||||
|
* 用 leftMax 和 rightMax 分别记录从左、右遇到的最高柱子
|
||||||
|
* 每次比较 height[left] 和 height[right]:
|
||||||
|
* 谁矮,就处理谁:因为能接水的高度取决于当前方向上历史最高柱子
|
||||||
|
* 用双指针减少了空间,整体时间仍然是 O(n)
|
||||||
|
* @param height
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int trap3(int[] height) {
|
||||||
|
int left = 0, right = height.length - 1;
|
||||||
|
int leftMax = 0, rightMax = 0;
|
||||||
|
int sum = 0;
|
||||||
|
|
||||||
|
while (left < right) {
|
||||||
|
if (height[left] < height[right]) {
|
||||||
|
if (height[left] > leftMax) {
|
||||||
|
leftMax = height[left];
|
||||||
|
} else {
|
||||||
|
sum += leftMax - height[left];
|
||||||
|
}
|
||||||
|
left++;
|
||||||
|
} else {
|
||||||
|
if (height[right] >= rightMax) {
|
||||||
|
rightMax = height[right];
|
||||||
|
} else {
|
||||||
|
sum += rightMax - height[right];
|
||||||
|
}
|
||||||
|
right--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
//单调栈 横着收集雨水
|
||||||
|
/**
|
||||||
|
* 使用一个单调递减栈(存的是索引),遇到比栈顶高的柱子,就说明可以接水了。
|
||||||
|
* 每当当前柱子比栈顶柱子高,就弹出栈顶作为“凹槽底部”,
|
||||||
|
* 然后新的栈顶变成“左边界”,当前柱子是“右边界”
|
||||||
|
* 这三者一起决定了可以接的水量:
|
||||||
|
* distance = i - stack.peek() - 1
|
||||||
|
* height = min(height[i], height[stack.peek()]) - height[top]
|
||||||
|
*
|
||||||
|
* 遇到不能接水的,就把当前柱子索引压入栈中,等待后面的柱子来形成边界
|
||||||
|
* @param height
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public int trap(int[] height) {
|
public int trap(int[] height) {
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
Deque<Integer> stack = new LinkedList<>();
|
Deque<Integer> stack = new LinkedList<>();
|
||||||
|
@ -16,6 +16,8 @@ package twopointers;
|
|||||||
输入:height = [1,1]
|
输入:height = [1,1]
|
||||||
输出:1
|
输出:1
|
||||||
*/
|
*/
|
||||||
|
//一刷不会
|
||||||
|
//二刷会做
|
||||||
public class MaxArea {
|
public class MaxArea {
|
||||||
|
|
||||||
//暴力解法O(N^2) 没过所有例子
|
//暴力解法O(N^2) 没过所有例子
|
||||||
|
@ -14,6 +14,7 @@ package twopointers;
|
|||||||
输出: [0]
|
输出: [0]
|
||||||
*/
|
*/
|
||||||
//做出了,但时间复杂度O(N^2)
|
//做出了,但时间复杂度O(N^2)
|
||||||
|
//二刷会做 ,时间复杂度on
|
||||||
public class MoveZeroes {
|
public class MoveZeroes {
|
||||||
public void moveZeroes1(int[] nums) {
|
public void moveZeroes1(int[] nums) {
|
||||||
for (int i = 0; i < nums.length; i++) {
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
@ -32,6 +32,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//做出来了
|
//做出来了
|
||||||
|
//二刷会做
|
||||||
public class ThreeSum {
|
public class ThreeSum {
|
||||||
public List<List<Integer>> threeSum(int[] nums) {
|
public List<List<Integer>> threeSum(int[] nums) {
|
||||||
List<List<Integer>> ans=new ArrayList<>();
|
List<List<Integer>> ans=new ArrayList<>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user