LeetCode 605 种花问题
https://leetcode-cn.com/problems/can-place-flowers/
题目描述:
假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。
可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),
和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?
能则返回True,不能则返回False。
输入: flowerbed = [1,0,0,0,1], n = 1
输出: True
输入: flowerbed = [1,0,0,0,1], n = 2
输出: False
* 数组内已种好的花不会违反种植规则。
* 输入的数组长度范围为 [1, 20000]。
* n 是非负整数,且不会超过输入数组的大小。
思路:
对于这道题来说,因为已经种好的花不会违反种植规则,所以对于每一个1,都有紧跟的0位置,可以跳过,所以,当当前位置值为1时,i = i+2;
而当当前位置为0时,前面肯定是0或者是起始位置,所以只需要看下一个位置的值,这个时候有一个临界条件,如果当前位置是数组末尾,此时是可种植的,如果不是,那么就需要看下一个位置的值,若是0,则可以种植,此时 i=i+2,若是1,则不能种植, i = i+1,到下一个位置。
代码如下:
class Solution {
public boolean canPlaceFlowers(int[] flowerbed, int n) {
int count = 0;
int len = flowerbed.length;
int i = 0;
while(i < len){
if(flowerbed[i] == 1){
i = i+2;
}
else {
if(i == len-1)
{
count++;
break;
}
if(flowerbed[i+1] == 0){
count++;
i = i+2;
}
else
i = i+1;
}
}
return count>= n;
}
}
leetcode 392 判断子序列
https://leetcode-cn.com/problems/is-subsequence/
题目描述:
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长
(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符
而不改变剩余字符相对位置形成的新字符串。
(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
思路:这里给出一种复杂度为O(n^2)的动态规划的思想,对于找到s在t中的相应的值,我们可以考虑使用一个dp[s.length()+1][t.length()+1]的数组来存储,dp[i][j] 表示当前长度为i的s序列是不是当前长度为j的t序列的子序列,可以写出一个转移方程:
- dp[i][j] = dp[i-1][j-1] if s.charAt(i) == t.charAt(j)
- dp[i][j] = dp[i][j-1] if s.charAt(i) != t.charAt(j)
如果当前的值相同,那么就看dp[i-1][j-1]的值,因为前面序列为子序列的话,那么肯定也是子序列,如果当前值不同,就看dp[i][j-1]的值,对于当前的s序列,长度为j-1的t序列是否包含。
class Solution {
public boolean isSubsequence(String s, String t) {
int[][] dp = new int[s.length()+1][t.length()+1];
for(int j = 0;j <= t.length();j++)
dp[0][j] = 1;
for(int i = 1;i <= s.length();i++)
dp[i][0] = 0;
for(int i = 1;i <= s.length();i++){
for(int j = 1; j <= t.length();j++){
if(s.charAt(i-1) == t.charAt(j-1)){
dp[i][j] = dp[i-1][j-1];
}
else{
dp[i][j] = dp[i][j-1];
}
}
}
return dp[s.length()][t.length()] == 1;
}
}
leetCode 665 非递减序列
https://leetcode-cn.com/problems/non-decreasing-array/
题目描述:
给定一个长度为 n 的整数数组,你的任务是判断在最多改变 1 个元素的情况下,
该数组能否变成一个非递减数列。
我们是这样定义一个非递减数列的:
对于数组中所有的 i (1 <= i < n),满足 array[i] <= array[i + 1]。
样例:
输入: [4,2,3]
输出: True
解释: 你可以通过把第一个4变成1来使得它成为一个非递减数列
思路:这是一道easy难度的题,想了好久才写出来,还是太菜了,需要多加练习啊。是要变化一次,让数组变为递增数组,可以设置一个count 记录变化的次数,变化的次数大于1次,那么说明无法完成。
对于nums[i] < nums[i-1],这说明此时需要变化,才能满足数组递增的要求,有两种情况:
- i-2 >= 0 && nums[i-2] > nums[i] do nums[i] = nums[i-1]
{此时nums[i-2] < nums[i-1],nums[i-2] > nums[i],为了保证数组递增且改变一个位置的值,只有改变nums[i]的值才能满足} - else nums[i-1] = nums[i]
{这时,nums[i-2] < nums[i-1] && nums[i-2] < nums[i],nums[i-1] > nums[i],为了满足改变一个位置的值保证数组递增,那么只有改变nums[i-1]的值}
代码如下:
class Solution {
public boolean checkPossibility(int[] nums) {
int count = 0;
for(int i = 1;i < nums.length;i++){
if(nums[i] < nums[i-1])
{
count++;
if(i-2 >= 0 && nums[i-2] > nums[i])
nums[i] = nums[i-1];
else
nums[i-1] = nums[i];
if(count > 1)
return false;
}
}
return true;
}
}
leetCode 53 最大子序和
https://leetcode-cn.com/problems/maximum-subarray/
题目描述:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组
(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
思路:
因为是要找到最大和的连续子数组,所以如果之前的序列和小于0的话是不需要加进去的,从当前位置开始可以得到最大的和,所以只需要定义两个变量,循环搜索一次就可以得到最佳的;
代码如下:
class Solution {
public int maxSubArray(int[] nums) {
if(nums.length == 1)
return nums[0];
int max = nums[0];
int ans = nums[0];
for(int i = 1;i < nums.length;i++){
max = max > 0 ? max+nums[i] : nums[i];
ans = Math.max(ans,max);
}
return ans;
}
}