1909.删除一个元素使数组严格递增
题目描述
给你一个下标从 0 开始的整数数组 nums ,如果 恰好 删除 一个 元素后,数组 严格递增 ,那么请你返回 true ,否则返回 false 。如果数组本身已经是严格递增的,请你也返回 true 。
数组 nums 是 严格递增 的定义为:对于任意下标的 1 <= i < nums.length 都满足 nums[i - 1] < nums[i] 。
示例 1:
输入:nums = [1,2,10,5,7]
输出:true
解释:从 nums 中删除下标 2 处的 10 ,得到 [1,2,5,7] 。
[1,2,5,7] 是严格递增的,所以返回 true 。
示例 2:
输入:nums = [2,3,1,2]
输出:false
解释:
[3,1,2] 是删除下标 0 处元素后得到的结果。
[2,1,2] 是删除下标 1 处元素后得到的结果。
[2,3,2] 是删除下标 2 处元素后得到的结果。
[2,3,1] 是删除下标 3 处元素后得到的结果。
没有任何结果数组是严格递增的,所以返回 false 。
示例 3:
输入:nums = [1,1,1]
输出:false
解释:删除任意元素后的结果都是 [1,1] 。
[1,1] 不是严格递增的,所以返回 false 。
示例 4:
输入:nums = [1,2,3]
输出:true
解释:[1,2,3] 已经是严格递增的,所以返回 true 。
解答
解1
自己的解法,不是很简洁
思路:找到不递增的两个数,若需要满足答案的条件,则必须删除一个,此时分两种情况判断删除后是否达成条件(删除前一个或删除后一个),若两种情况都不行,则返回false,两种有一种成功了,返回true
o(n^2)
class Solution {
public boolean canBeIncreasing(int[] nums) {
if(isTrue(nums,-1)){
return true;
}
for(int i = 1;i < nums.length;i++){
if(nums[i] <= nums[i - 1]){
if(isTrue(nums,i) || isTrue(nums,i - 1)){
return true;
}else{
return false;
}
}
}
return true;
}
public boolean isTrue(int[] nums,int index){
for(int i = 1;i < nums.length;i++){
if(index != -1){
if(i == index){
continue;
}else if(i - 1 == index && i == 1){
continue;
}else if(i - 1 == index){
if(nums[i] <= nums[i - 2]){
return false;
}
}else{
if(nums[i] <= nums[i - 1]){
return false;
}
}
}else{
if(nums[i] <= nums[i - 1]){
return false;
}
}
}
return true;
}
}
解2
贪心
找到不一样的,判断需要删除i还是i-1即可
如果删除nums[i] nums[i] = nums[i - 1]
如果删除nums[i - 1] nums[i - 1] = nums[i]
一次遍历 o(n)
class Solution {
public boolean canBeIncreasing(int[] nums) {
int cnt = 0;
for (int i = 1; i < nums.length && cnt <= 1; i++) {
if (nums[i] > nums[i - 1]) continue;
cnt++;
if (i - 1 > 0 && nums[i] <= nums[i - 2]) {
nums[i] = nums[i - 1];
} else {
nums[i - 1] = nums[i];
}
}
return cnt <= 1;
}
}
1910. 删除一个字符串中所有出现的给定子字符串
题目描述
给你两个字符串 s 和 part ,请你对 s 反复执行以下操作直到 所有 子字符串 part 都被删除:
- 找到 s 中 最左边 的子字符串 part ,并将它从 s 中删除。
请你返回从 s 中删除所有 part 子字符串以后得到的剩余字符串。 - 一个 子字符串 是一个字符串中连续的字符序列。
示例 1:
输入:s = “daabcbaabcbc”, part = “abc”
输出:“dab”
解释:以下操作按顺序执行:
s = “daabcbaabcbc” ,删除下标从 2 开始的 “abc” ,得到 s = “dabaabcbc” 。
s = “dabaabcbc” ,删除下标从 4 开始的 “abc” ,得到 s = “dababc” 。
s = “dababc” ,删除下标从 3 开始的 “abc” ,得到 s = “dab” 。
此时 s 中不再含有子字符串 “abc” 。
示例 2:
输入:s = “axxxxyyyyb”, part = “xy”
输出:“ab”
解释:以下操作按顺序执行:
s = “axxxxyyyyb” ,删除下标从 4 开始的 “xy” ,得到 s = “axxxyyyb” 。
s = “axxxyyyb” ,删除下标从 3 开始的 “xy” ,得到 s = “axxyyb” 。
s = “axxyyb” ,删除下标从 2 开始的 “xy” ,得到 s = “axyb” 。
s = “axyb” ,删除下标从 1 开始的 “xy” ,得到 s = “ab” 。
此时 s 中不再含有子字符串 “xy” 。
提示:
1 <= s.length <= 1000
1 <= part.length <= 1000
s 和 part 只包小写英文字母。
解答
解1
StringBuilder
class Solution {
public String removeOccurrences(String s, String part) {
StringBuilder sb = new StringBuilder(s);
while(sb.indexOf(part) != -1){
int index = sb.indexOf(part);
sb.delete(index,index + part.length());
}
return sb.toString();
}
}
1911. 最大子序列交替和
题目描述
一个下标从 0 开始的数组的 交替和 定义为 偶数 下标处元素之 和 减去 奇数 下标处元素之 和 。
比方说,数组 [4,2,5,3] 的交替和为 (4 + 5) - (2 + 3) = 4 。
给你一个数组 nums ,请你返回 nums 中任意子序列的 最大交替和 (子序列的下标 重新 从 0 开始编号)。
一个数组的 子序列 是从原数组中删除一些元素后(也可能一个也不删除)剩余元素不改变顺序组成的数组。比方说,[2,7,4] 是 [4,2,3,7,2,1,4] 的一个子序列(加粗元素),但是 [2,4,2] 不是。
示例 1:
输入:nums = [4,2,5,3]
输出:7
解释:最优子序列为 [4,2,5] ,交替和为 (4 + 5) - 2 = 7 。
示例 2:
输入:nums = [5,6,7,8]
输出:8
解释:最优子序列为 [8] ,交替和为 8 。
示例 3:
输入:nums = [6,2,1,2,4,5]
输出:10
解释:最优子序列为 [6,1,5] ,交替和为 (6 + 5) - 1 = 10 。
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 105
解答
解1
DP状态机
状态定义:
- f[i][0]:前i个数中选中偶数个数的最大交替和
- f[i][0]:前i个数中选中奇数个数的最大交替和
class Solution {
public long maxAlternatingSum(int[] nums) {
int l = nums.length;
long[][] dp = new long[l + 1][2];
for(int i = 0;i <= l;i++){
//防止溢出
Arrays.fill(dp[i],Integer.MIN_VALUE >> 1);
}
dp[0][0] = 0;
for(int i = 1;i <= l;i++){
//前i个数的偶数个数交替最大值,从奇数个数个的交替最大和中转移
dp[i][0] = Math.max(dp[i - 1][0],dp[i - 1][1] - nums[i - 1]);
//同理
dp[i][1] = Math.max(dp[i - 1][1],dp[i - 1][0] + nums[i - 1]);
}
return Math.max(dp[l][1],dp[l][0]);
}
}
解2
解一定是奇数个值
找到第一个最大值,然后两两对比判断是否为正收益(nums[i] > nums[i - 1]),是,就加入,不是,找下一组
class Solution {
public long maxAlternatingSum(int[] nums) {
long first = nums[0];
int index = 1;
while(index < nums.length){
if(nums[index] > first){
first = nums[index];
index++;
}else{
break;
}
}
if(index == nums.length){
return first;
}
long res = first;
index++;
while(index < nums.length){
if(nums[index] > nums[index - 1]){
res += nums[index] - nums[index - 1];
}
index++;
}
return res;
}
}