做题
今天没有做每日一题,感觉今天的题也不好做,而且最近比较忙,下午是虎牙面试,晚上是美团笔试,还要做下周的ppt,所以就看了数组的几个题,下面说一下
删除排序数组的重复项
看到删除也不能马上从删除的角度考虑,如果真的去删除的话,时间复杂度确实会比较大。
这里可以考虑两个游标,i游标用于构建不存在重复元素的数组,j游标用于遍历整个数组。当j游标找到一个不重复的数的时候就在i游标处赋值,下面看一下代码
public int removeDuplicates(int[] nums) {
int length = nums.length;
if(length == 0) return 0;
/**
不需要真的去删除,因为是排序数组
用j找到和i不同的数字,赋值给++i,
即可以以i构建一个包含不同数字的数
组,长度就是i+1
**/
int i=0;
for(int j=0;j<length;j++) {
if(nums[i] != nums[j]) {
i++;
nums[i] = nums[j];
}
}
return i+1;
}
买卖股票的最佳时机II
这个看到我自己以前写的解法,大几十行,就没看。再次做的时候马上就想到了更好的解法,可能也算是一点进步吧。
因为这个买卖股票的题是可以多次卖出股票来获得最大收益,那么在逻辑上只要在每次波谷买入,波峰卖出就可以了。但实际上也并不需要真的去探测波峰波谷,只要第i天比第i-1天打,那么就加上这两天的差值即可。下面看代码
public int maxProfit(int[] prices) {
int length = prices.length;
if(length == 0) return 0;
/**
因为只需要在波谷和波峰卖掉股票
所以只要是第i天比第i-1天股价高
那么就直接加上这个差价
**/
int ans = 0;
for(int i=1;i<length;i++){
int diff = prices[i] - prices[i-1];
if(diff > 0){
ans += diff;
}
}
return ans;
}
旋转数组
这个题方法很多,讲一个比较好的方法。
把整个数组翻转,然后在分别翻转前k个和后n-k个。这里需要注意一下对于k>n的情况进行处理。
public void rotate(int[] nums, int k) {
k %= nums.length;//注意处理k>length的情况
reverse(nums, 0, nums.length - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, nums.length - 1);
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}