42. 接雨水 - 力扣(LeetCode)
思路:当前列雨水面积:min(左边柱子的最高高度,记录右边柱子的最高高度) - 当前柱子高度。
为了得到两边的最高高度,使用了双指针来遍历,每到一个柱子都向两边遍历一遍,这其实是有重复计算的。我们把每一个位置的左边最高高度记录在一个数组上(maxLeft),右边最高高度记录在一个数组上(maxRight),这样就避免了重复计算。
当前位置,左边的最高高度是前一个位置的左边最高高度和本高度的最大值。
即从左向右遍历:maxLeft[i] = max(height[i], maxLeft[i - 1]);
从右向左遍历:maxRight[i] = max(height[i], maxRight[i + 1]);
class Solution {
public int trap(int[] height) {
//使用双指针进行做
int length=height.length;
if(length<=2) return 0;
int [] leftMax=new int[length];
int [] rigthMax=new int[length];
// 记录每个柱子左边柱子最大高度
leftMax[0] =height[0];
for(int i=1;i<length;i++){
leftMax[i]=Math.max(height[i],leftMax[i-1]);
}
// 记录每个柱子右边柱子最大高度
rigthMax[length-1]=height[length-1];
for(int j=length-2;j>=0;j--){
rigthMax[j]=Math.max(height[j],rigthMax[j+1]);
}
// 求和
int sum=0;
for(int i=0;i<length;i++){
int count=Math.min(leftMax[i],rigthMax[i])-height[i];
sum+=count;
}
return sum;
}
}
3. 无重复字符的最长子串 - 力扣(LeetCode)
可以把"窗口"想象成字符串中满足条件(无重复字符)的一段区间 [left, right]。
-
我们使用两个指针
left和right来表示窗口的左右边界,初始都为 0。 -
right指针主动向右遍历字符串,将新字符加入窗口。 -
如果加入的新字符在窗口中已经存在 (即出现了重复),我们就需要收缩窗口:将
left指针向右移动,直到窗口内不再包含该重复字符为止。 -
在这个过程中,每次窗口处于"无重复"状态时,我们就记录一下当前窗口的长度
right - left + 1,并更新最大长度。class Solution {
public int lengthOfLongestSubstring(String s) {
// 记录字符及其最近一次出现的索引
HashMap<Character, Integer> map = new HashMap<>();
int left=0;
int maxLength=0;
for(int right=0;right<s.length();right++){
char str=s.charAt(right);
// 如果遇到了重复字符,且该字符在当前窗口内
if(map.containsKey(str)&&map.get(str)>=left){
left = map.get(str) + 1;
}
// 将字符及当前索引放入/更新到哈希表中
map.put(str, right);
// 计算当前无重复子串长度,更新最大值
maxLength=Math.max(maxLength,right-left+1);
}
return maxLength;
}
}