1646. 获取生成数组中的最大值
给你一个整数 n
。按下述规则生成一个长度为 n + 1
的数组 nums
:
nums[0] = 0
nums[1] = 1
2 <= 2 * i <= n
时,nums[2 * i] = nums[i]
2 <= 2 * i + 1 <= n
时,nums[2 * i + 1] = nums[i] + nums[i + 1]
返回生成数组 nums
中的 最大 值。
示例 1:
输入:n = 7
输出:3
解释:根据规则:
nums[0] = 0
nums[1] = 1
nums[(1 * 2) = 2] = nums[1] = 1
nums[(1 * 2) + 1 = 3] = nums[1] + nums[2] = 1 + 1 = 2
nums[(2 * 2) = 4] = nums[2] = 1
nums[(2 * 2) + 1 = 5] = nums[2] + nums[3] = 1 + 2 = 3
nums[(3 * 2) = 6] = nums[3] = 2
nums[(3 * 2) + 1 = 7] = nums[3] + nums[4] = 2 + 1 = 3
因此,nums = [0,1,1,2,1,3,2,3],最大值 3
示例 2:
输入:n = 2
输出:1
解释:根据规则,nums[0]、nums[1] 和 nums[2] 之中的最大值是 1
class Solution {
public int getMaximumGenerated(int n) {
if(n==0){
return 0;
}
int[]dp=new int[101];
dp[0]=0;
dp[1]=1;
int max=1;//由于创建n+1长度数组,所以max初始值设置为1
for(int i=2;i<=n;i++){
if(i%2==0){
dp[i]=dp[i/2];
}
else{
dp[i]=dp[i/2]+dp[i/2+1];
}
max=max>dp[i]?max:dp[i];
}
return max;
}
}
简单题感觉没啥说的了,细心点就好~~~
怎么说呢,感觉也做了不少,自己还是很难做到举一反三,一个新题型就给我干趴了。。
1043. 分隔数组以得到最大和
给你一个整数数组 arr
,请你将该数组分隔为长度 最多 为 k 的一些(连续)子数组。分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值。
返回将数组分隔变换后能够得到的元素最大和。本题所用到的测试用例会确保答案是一个 32 位整数。
示例 1:
输入:arr = [1,15,7,9,2,5,10], k = 3
输出:84
解释:数组变为 [15,15,15,9,10,10,10]
示例 2:
输入:arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4
输出:83
示例 3:
输入:arr = [1], k = 1
输出:1
对大佬们来说这个题简简单单,但是差点给孩子道心干碎了,┭┮﹏┭┮
后面看了有个大佬解释,又是想给自己来一下。不过好歹是懂了
class Solution {
static public int maxSumAfterPartitioning(int[] arr, int k) {
int len=arr.length;
int[]dp=new int[len+1];
if(len==1){
return arr[0];
}
//i代表已经划分好前面多少个数字了
for(int i=1;i<=len;i++){
int max=0;
//如同跳阶梯一样,dp[i]由dp[i-1]到dp[i-k]决定,所以设置j为1~k
for(int j=1;j<=i&&j<=k;j++){
max=max>arr[i-j]?max:arr[i-j];
dp[i]=Math.max(dp[i],dp[i-j]+j*max);
}
}
return dp[len];
}
}
下面这个题感觉也是思路挺像的
139. 单词拆分
给你一个字符串 s
和一个字符串列表 wordDict
作为字典。请你判断是否可以利用字典中出现的单词拼接出 s
。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
示例 1:
输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
示例 2:
输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
注意,你可以重复使用字典中的单词。
示例 3:
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int len=s.length();
int l=0;
boolean []dp=new boolean[len+1];
dp[0]=true;
//i为已经配对好的字母个数
//leet code leetcode
for(int i=1;i<=len;i++){
//单词进行一一比对
for(int j=0;j< wordDict.size();j++){
l=wordDict.get(j).length();
if(i<l){
continue;
}
//dp由dp[i-l]以及i-l,i这段是否能够匹配单词库决定
if(dp[i-l] &&s.substring(i-l,i).equals(wordDict.get(j))){
dp[i]=true;
}
}
}
return dp[len];
}
}
感觉现在做动态规划就是,老是容易急躁。。大概也是自己性格问题,w(゚Д゚)w
嘛,最后做一个晚上再总结一下,给自己缓缓。
**1869. 哪种连续子字符串更长**
给你一个二进制字符串 s
。如果字符串中由 1
组成的 最长 连续子字符串 严格长于 由 0
组成的 最长 连续子字符串,返回 true
;否则,返回 false
。
s = "**11**01**000**10"
中,由 1
组成的最长连续子字符串的长度是 2
,由 0
组成的最长连续子字符串的长度是 3
。注意,如果字符串中不存在 0
,此时认为由 0
组成的最长连续子字符串的长度是 0
。字符串中不存在 1
的情况也适用此规则。
示例 1:
输入:s = "1101"
输出:true
解释:
由 1 组成的最长连续子字符串的长度是 2:"1101"
由 0 组成的最长连续子字符串的长度是 1:"1101"
由 1 组成的子字符串更长,故返回 true 。
示例 2:
输入:s = "111000"
输出:false
解释:
由 1 组成的最长连续子字符串的长度是 3:"111000"
由 0 组成的最长连续子字符串的长度是 3:"111000"
由 1 组成的子字符串不比由 0 组成的子字符串长,故返回 false 。
示例 3:
输入:s = "110100010"
输出:false
解释:
由 1 组成的最长连续子字符串的长度是 2:"110100010"
由 0 组成的最长连续子字符串的长度是 3:"110100010"
由 1 组成的子字符串不比由 0 组成的子字符串长,故返回 false 。
额,一不小心好像直接暴力了。。az
class Solution {
public boolean checkZeroOnes(String s) {
int len=s.length();
int dp[len+1][2];
dp[0][0]=dp[0][1]=0;
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='1'){
temp1++;
temp0=0;
if(max1<temp1){
max1=temp1;
}
}
else{
temp0++;
temp1=0;
if(max0<temp0){
max0=temp0;
}
}
}
return max1>max0;
}
}
就先到这吧,感觉得打打基础,评论区那些暴力枚举,回溯,正则。
算是知道名字,但是完全没一点想法。感觉算法还是得先广撒网,然后逐渐深入。