26、难度简单:
本题易忽视点:
1、该数组是有序的
2、返回(return)数值是整数,但输出的答案是数组。假设你的返回数是n,那网站就会把数组nums的0~n-1的元素打印出来和删去重复项的原数组进行比较,若相同那你的代码就会通过
给你一个有序数组 nums ,请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
//双指针解决
public int removeDuplicates(int[] A) {
//边界条件判断
if (A == null || A.length == 0)
return 0;
int left = 0;
for (int right = 1; right < A.length; right++)
//如果左指针和右指针指向的值一样,说明有重复的,
//这个时候,左指针不动,右指针继续往右移。如果他俩
//指向的值不一样就把右指针指向的值往前挪
if (A[left] != A[right])
A[++left] = A[right];
return ++left;
}
因为有序,所以我们不用担心在元素由1过渡到2后还会在后续位置处遇到元素1
先举2个极端例子:
1、如果数组中一个重复项都没有,那么left会一直+1,但由于left是从0开始加的,所以最后return时还需要再++。
2、如果全是相同的一项,那么left会一直不变,直到最后return+1。
先判断传进来的数组是否为空或者元素个数为1,若为空或元素个数为1那么直接return 0,否则
1、先定义变量left作为数组的左指针和修改后数组的新长度。并定义其数值为0
2、开始循环,定义右指针right数值为1。
3、如果数值上左指针等于右指针,左指针不变右指针+1:
①、由于左指针数值同时也是新数组长度,所以在出现重复后我们可以直接略去也就是当做删除该元素。
②、循环一轮后右指针+1说明开始比对下一项元素(该元素可能和left相同或不同)
4、若数值上二者不相等:
①、左指针+1相当于往新数组里添加一个有效元素
②、右指针不变原因:right会在每次循环后+1,无需加1
③、就结果而论两指针都加一,直接比对下一项元素。
5、新数组的产生:
①、A[0]项无需变动,因为就算有重复也是删去0位置后1等位置的元素。
②、可以把A[left]看成新数组,A[right]看做原数组。由于是在原数组进行改动,而一开始right大于left1个位置,所以我们可以直接从A[right]中抽取元素填充新数组A[left]。因为right会在每轮循环后自动+1,只要二者不相等那就会赋值给当前A[left],同时left再+1为下次存值创建空间。而二者相同left数值就不变也不会给A[left]赋值,right+1直接无视掉这个重复项,这个过程等同于删除。
122、难度中等:
暴力求解:直接把所有可能的利润相加,代码如下:
class Solution {
public int maxProfit(int[] arr) {
//若数组元素不达标就返回
if (arr == null || arr.length <= 1) return 0;
int ans = 0;
for (int i = 1; i < arr.length; i++) {
// 只要后一项大于前一项那就加到总(最大)利润里
if (arr[i] > arr[i-1]) {
ans += (arr[i] - arr[i-1]);
}
}
return ans;
}
}
本题的烟雾弹:题目给出的示例2原文如下:
输入: prices = [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
烟雾弹①、在描述解释时官方采用第一天买入第五天卖出来获得最大利益5-1=4,然而我们第一天买入第二天卖出可获得利润2-1=1,第二天买入第三天卖出获利1,同理到第五天我们总共获利为1+1+1+1也=4。因此我们不需要把本题想得过于复杂,直接后一项大于前一项就相加即可。
烟雾弹②、本题给出的两条语句
“你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)”和
“注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。”
意思是你可以在第二天卖完第一天的股票后再买第二天的股票。而不能在买了第一天股票的前提下去买第二天的股票。
为什么只要相加差值就可以得到最大利润,用下图来解释:
无论数组prices里的元素是什么,怎样的顺序,都离不开上图的模式,也就是上升趋势和下降趋势。而上图可以直观的给出,最大利润就是红线(上升趋势)的总和,因为除了上升就是亏损,你不可能选亏损的蓝线,你只能选红线。
可能会存在如果我选择第1天买第6天卖是否会有变化:因为可能存在第一天价格为1,第5天价格为59,第六天价格为60,
这样看似60-1=59>60-59=1,但其实结合上图稍加思考就会发现这么做你只会亏损,因为我们的实际获利也可以看做是两两点y轴差值的总和,并且你第一天是1,第六天是60,线是连起来的,你必然会有连接性的上升,所以必然把前面的累加起来可以达到60-1=59,甚至因为曲折还能多出59以外的利润。