题目1
题解
- 状态定义:dp[i] 表示 s[0…i-1] 是否能被拆分成若干个单词表单词
- 状态转移方程:
dp[i] = dp[j] && s[j...i]也在字典单词中,j<i
,j之前的子串是单词表单词,j到i的子串也是单词表单词 - 初始条件:dp[0]=true
- 返回值:dp[n]
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int n=s.length();
Set<String>wordSet=new HashSet<>(wordDict);//哈希表存字典
boolean[] dp=new boolean[n+1];
dp[0]=true;
for(int i=1;i<n+1;i++){
for(int j=0;j<i;j++){
if(dp[i]) break;//剪枝
if(dp[j]&&wordSet.contains(s.substring(j,i))){
dp[i]=true;
break;
}
}
}
return dp[n];
}
}
时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( n ) O(n) O(n)
题目2
题解
动态规划
刷的第一道困难题,经典的动态规划,大概是需要熟读背诵吧
对于下标 i,下雨后水能到达的最大高度等于下标 i 两边的最大高度的最小值,下标 i 处能接的雨水量等于下标 i 处的水能到达的最大高度减去 height[i]。
- 状态定义:leftMax[i] 表示下标 i 及其左边的位置中,height 的最大高度;rightMax[i] 表示下标 i 及其右边的位置中,height 的最大高度
- 状态转移方程:
从前向后更新leftMax[i]:leftMax[i]=max(leftmax[i-1],height[i]), 1<=i<=n-1
;
从后向前更新rightMax[i]:rightMax[i]=max(rightMax[i+1],height[i]),1<=i<=n-2
;
最终:res+ = min(leftMax[i],rightMax[i])-height[i]
,res为能接到的雨水总量。 - 初始条件:leftMax[0]=height[0];rightMax[n-1]=height[n-1]
- 返回值:res
class Solution {
public int trap(int[] height) {
int n=height.length,res=0;
int[] leftMax=new int[n];
int[] rightMax=new int[n];
leftMax[0]=height[0];
rightMax[n-1]=height[n-1];
//左边最大值
for(int i=1;i<n;i++){
leftMax[i]=Math.max(leftMax[i-1],height[i]);
}
//右边最大值
for(int i=n-2;i>0;i--){
rightMax[i]=Math.max(rightMax[i+1],height[i]);
}
for(int i=1;i<n-1;i++){
res+=Math.min(leftMax[i],rightMax[i])-height[i];
}
return res;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)
单调栈
- 单调栈按照行计算
- 单调栈内元素顺序
应该是栈底到栈顶递减顺序
因为一旦发现添加的柱子高度大于栈顶元素了,此时就出现凹槽了,栈顶元素就是凹槽底部的柱子,栈顶第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。
如图,
- 遇到相同高度的柱子怎么办
遇到相同元素,需要更新栈内下标
因为求宽度的时候,如果遇到相同高度的柱子,要用最右边的柱子来计算宽度。
如图,需要把第一个5弹出,再把第二个5入栈,
class Solution {
public int trap(int[] height) {
int n=height.length,res=0;
Deque<Integer>stk=new LinkedList<>();
for(int i=0;i<n;i++){
while(!stk.isEmpty()&&height[i]>height[stk.peek()]){
int mid=stk.pop();
if(!stk.isEmpty()){
int h=Math.min(height[stk.peek()],height[i])-height[mid];
int w=i-stk.peek()-1;
res+=h*w;
}
}
stk.push(i);
}
return res;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)