删除排序数组中的重复项
双指针解题代码思路
int removeDuplicates(int* nums, int numsSize){
int i=0,j=1;
for (j=1; j<numsSize; j++) {
if (i+1==j && nums[i] != nums[j]) {//i,j相邻且不等,都向后移动
i++;
}else if (nums[i] == nums[j]) {//相等,只有j向后移动
}else if (nums[i] != nums[j]) {//不相邻,且不等,i后移,j赋值给i
i++;
nums[i] = nums[j];
}
}
return i+1;
}
简化代码
int removeDuplicates(int* nums, int numsSize){
int i=0;
for (int j=1; j<numsSize; j++) {
if (nums[i] != nums[j]) {
i++;
if (i!=j) nums[i] = nums[j];//这句判断可以不加,相当于自己赋值给自己
}
}
return i+1;
}
复杂度分析:
时间复杂度:O(n)。
空间复杂度:O(1)。
买卖股票的最佳时机 II
计算相邻两天的差值,为正就累加到利润里就可以了
int maxProfit(int* prices, int pricesSize){
int sum = 0;
for (int i=0; i<pricesSize-1; i++) {
if (prices[i+1] > prices[i]) {
sum = sum + prices[i+1]-prices[i];
}
}
return sum;
}
复杂度分析:
时间复杂度:O(n),遍历一次。
空间复杂度:O(1),需要常量的空间。
旋转数组
方法一
每次所有数向右移动一位,移动k次
void rotate(int* nums, int numsSize, int k){
int t = 0;
for (int i=0; i<k; i++) {
t = nums[numsSize-1];//记下最后一个数
for (int j=0; j<numsSize-1; j++) {
nums[numsSize-1-j] = nums[numsSize-2-j];//依次向右移动一位,移动numsSize-1次
}
nums[0] = t;//把最后一位给到第一位
}
}
复杂度分析
时间复杂度:O(n*k) 。每个元素都被移动 1 步(O(n)) k次(O(k)) 。
空间复杂度:O(1)。没有额外空间被使用。
方法二
环装替换让第一个数向右移动k,并替换。被替换数也向右移动k,替换...以此类推,替换n次
void rotate(int* nums, int numsSize, int k){
int n=0, t=0, num = nums[0], j = 0;//n为第一个移动的数,t交换数用,num存被替换的数,j记录num的角标
for (int i=0; i<numsSize; i++) {//替换numsSize次
int m = (j+k)%numsSize;//m为被替换数的角标
t = nums[m];
nums[m] = num;//替换
if (n == m) {//如果被替换数已经m已经等于n了,继续替换就重复了,所以向n后一位移动,再开始替换
n = m+1>numsSize-1?0:m+1;//如果向后一位造成数组越界,那么把0赋值给n
j = n;
num = nums[j];//更新num
}else {
j = m;
num = t;//把被替换数存到num里
}
}
}
复杂度分析
时间复杂度:O(n) 。
空间复杂度:O(1)。没有额外空间被使用。
网友评论