输入: [4,2,3]
输出: True
解释: 你可以通过把第一个4变成1来使得它成为一个非递减数列。
class Solution {
public boolean checkPossibility(int[] a) {
/*
定义常量来计算交换的次数
如果出现a[i]>a[i+1];应该让a[i]=a[i+1],变小,才不会影响后续操作
如果有a[i-2]=a[i-1]>a[i]情况,应该让a[i]=a[i-1]
*/
int cnt=0;
for(int i=1;i<a.length&&cnt<2;i++){
if(a[i]>=a[i-1]){
continue;
}
cnt++;
if(i-2>=0&&a[i]<a[i-2]){
a[i]=a[i-1];
}else{
a[i-1]=a[i];
}
}
return cnt<=1;
}
}
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
思路:可以计算出相邻的两个数组元素满足a[i]>a[i-1];然后进行累加
如果a<=b<=c<=d,那么profile=(d-a)=(b-a)+(c-b)+(d-c)局部最优即全局最优
对于 [a, b, c, d],如果有 a <= b <= c <= d ,那么最大收益为 d - a。而 d - a = (d - c) + (c - b) + (b - a) ,因此当访问到一个 prices[i] 且 prices[i] - prices[i-1] > 0,那么就把 prices[i] - prices[i-1] 添加到收益中,从而在局部最优的情况下也保证全局最优。
class Solution {
public int maxProfit(int[] prices) {
int profile=0;
for(int i=1;i<prices.length;i++){
if(prices[i]>prices[i-1]){
profile+=prices[i]-prices[i-1];
}
}
return profile;
}
}
最大子序列的和:贪心思想:保证了每次的和从非负数开始
class Solution {
public int maxSubArray(int[] nums) {
/*定义一个指针作对照,另外一个元素从1开始遍历*/
int presum=nums[0];
int maxsum=presum;
for(int i=1;i<nums.length;i++){
presum=presum>0?presum+nums[i]:nums[i];
maxsum=Math.max(maxsum,presum);
}
return maxsum;
}
}
输入: [7,1,5,3,6,4] 输出: 5
先求出最小的买入价格,然后求出买入价格后期的卖出价格;因为一天的股票要么是买入要么是卖出。如果小于最小股票,就进行买入,否则卖出,并找到卖出的最大利润。
class Solution {
public int maxProfit(int[] prices) {
if(prices.length==0)return 0;
int minCurnum=prices[0];
int max=0;
for(int i=1;i<prices.length;i++){
if(prices[i]<minCurnum){
minCurnum=prices[i];
}else{
max=Math.max(max,prices[i]-minCurnum);
}
}
return max;
}
}