一.单词拆分
问题概述:
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。


思路:
一个字符串可不可以拼接,可以将其拆分成两部分看,如果前部分是可以拆分的并且剩下一部分刚好在wordDict当中,那这个字符串就是可以拼接的。
代码:
javascript
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
Set<String> worldSet=new HashSet<>(wordDict);
int n=s.length()+1;
boolean[] dp=new boolean[n];
dp[0]=true;
for(int i=1;i<n;i++){
for(int j=0;j<i;j++){
if(dp[j]&&worldSet.contains(s.substring(j,i))){
dp[i]=true;
break;
}
}
}
return dp[n-1];
}
}
二.最长递增子序列
问题概述:


思路:
每个元素本身可以构成1个子序列,那dp\[\]初值都设为1。
那后面新加的numsi比前面numsj大就选numsi和numsj+1大的那个,
例如:nums=10,1,2,5
10 dp0=1
新加1 1<10 dp1=1
新加2 2<10 2>1 dp2=max(dp1+1,dp2)
新加5 5<10 5>1 dp3=max(dp1+1,dp3) 5>2 dp3=max(dp2+1,dp3)
代码:
java
class Solution {
public int lengthOfLIS(int[] nums) {
int n=nums.length;
int[] dp=new int[n];
int maxn=1;
for(int i=0;i<n;i++){
dp[i]=1;
}
for(int i=1;i<n;i++){
for(int j=0;j<i;j++){
if(nums[i]>nums[j]){
dp[i]=Math.max(dp[j]+1,dp[i]);
}
}
maxn=Math.max(maxn,dp[i]);
}
return maxn;
}
}
三.乘积最大子数组
问题概述:

思路:
新加一个numsi,那此刻包含这个数的最大数要么就是正正 负负 本身得到的
代码:
java
class Solution {
public int maxProduct(int[] nums) {
int max=nums[0];
int min=nums[0];
int res=nums[0];
int n=nums.length;
for(int i=1;i<n;i++){
int tempmax=max;
int tempmin=min;
max=Math.max(nums[i],Math.max(tempmax*nums[i],tempmin*nums[i]));
min=Math.min(nums[i],Math.min(tempmax*nums[i],tempmin*nums[i]));
res=Math.max(res,max);
}
return res;
}
}
四.分割等和子集
问题概述:
给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

思路:
就是看能不能凑成总数的一半,如果总数和为奇数则可以直接返回false了,如果为偶数进一步判断,dp11是否为true,因为所给的nums本身不是有序的,所以需要每个遍历,
num=1
dp11=dp11||dp11-1
dp10=dp10||dp10-1
...
dp1=dp1||dp1-1=true
此时只有dp0、dp1为true
num=5
dp11=dp11||dp11-5
dp10=dp10||dp10-5
...
dp5=dp5||dp0
此时dp0、dp1、dp5为true
num=11
dp11=dp11||dp11-11 为true 现在已结束,dp0、dp1、dp5、dp11为true
代码:
java
class Solution {
public boolean canPartition(int[] nums) {
int sum=0;
for(int num : nums){
sum+=num;
}
if(sum%2==1){
return false;
}
int target=sum/2;
boolean[] dp=new boolean[target+1];
dp[0]=true;
for(int num:nums){
for(int j=target;j>=num;j--){
dp[j]=dp[j]||dp[j-num];
}
}
return dp[target];
}
}
五.最长有效括号
问题概述:
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号 子串 的长度。
左右括号匹配,即每个左括号都有对应的右括号将其闭合的字符串是格式正确的,比如 "(()())"为6.

思路:
dpi表示以索引为i结尾的最长有效括号子串的长度。
①当结尾为'(',就是不合法的,就记0.
②当结尾为')', a.dpi-1为'(' :dpi=di-2+2
b.dpi-1为')' : 需满足dpi-dp\[i-1-1]=='('才能包起来,然后dpi=dpi-1+2+dpi-dp\[i-dp\[i-1-2]
注意:越界条件判断
代码:
java
class Solution {
public int longestValidParentheses(String s) {
int n=s.length();
if(n<2){
return 0;
}
int[] dp=new int[n];
int max=0;
for(int i=1;i<n;i++){
if(s.charAt(i)==')'){
if(s.charAt(i-1)=='('){
dp[i]=i-2>=0 ? dp[i-2]+2 : 2;
}else if(s.charAt(i-1)==')'){
if(i-dp[i-1]-1>=0&&s.charAt(i-dp[i-1]-1)=='('){
dp[i]=i-dp[i-1]-2>=0 ? dp[i-1]+2+dp[i-dp[i-1]-2] : dp[i-1]+2;
}
}
}
max=Math.max(max,dp[i]);
}
return max;
}
}