leetcode刷题第二天——数组之移除数组元素

本次刷题顺序是按照卡尔的代码随想录中给出的顺序

数组是存放在连续内存空间上的相同类型的数据的集合。可以实现随机访问,但是增加和移除元素,需要挪动数组中的相关元素。

在移除数组元素时,可能要求保持数组元素相对顺序不变,此时一般可以使用快慢指针来解题

在数组中,双指针和二分法是比较常用的思想,多练多练多练

27. 移除元素

int removeElement(int* nums, int numsSize, int val) {
    int l = 0, r = numsSize - 1;
    while(l <= r) {//当只有一个元素是,初始的l与r相等,
        while(l <= r && nums[l] != val) l++;//从左边找是val的值
        while(l <= r && nums[r] == val) r--;//从右边找不是val的值
        if(l < r) {//如果满足条件,那么将nums[r]的值赋值给nums[l],因为,满足l <= r情况下,l是找到等于val且r找到不等于val
            nums[l] = nums[r];
            l++;
            r--;
        }
    }
    return l;
}

26. 删除有序数组中的重复项

/*使用快慢指针法,在不考虑越界的情况下,
识别到快慢指针指向的值相同,则快指针加1,否则,将快指针的值赋值给慢指针的下一个位置*/
int removeDuplicates(int* nums, int numsSize) {
    int slow = 0, qiuck = 0;
    while(qiuck < numsSize) {
        while(qiuck < numsSize && nums[qiuck] == nums[slow]) qiuck++;
        if(qiuck < numsSize) nums[++slow] = nums[qiuck];
    }
    return slow + 1;
}

283. 移动零

/*采用快慢指针法,qiuck找不等于0的数组元素,找到后,如果slow对应的数组元素为0,则交换两者的值。
无论是否能够交换,都slow和qiuck都指向下一个位置*/
void swap(int* a, int* b) {
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

void moveZeroes(int* nums, int numsSize) {
    int slow = 0, qiuck = 0;
    while(qiuck < numsSize) {
        while(qiuck < numsSize && nums[qiuck] == 0) qiuck++;
        if(qiuck < numsSize && nums[slow] == 0) swap(&nums[slow], &nums[qiuck]); 
        slow++;  qiuck++;
    }
}

844. 比较含退格的字符串

void GetString(char* a) {//重构字符串,得到抵消退格后的字符串
    int slow = 0, qiuck = 0, cnt;
    while(a[qiuck] != '\0') {
        cnt = 0;
        while(a[qiuck] != '\0' && a[qiuck] == '#') {//统计‘#’出现的次数
            qiuck++;
            cnt++;
        }
        if (cnt != 0) {//计算退格后,slow的指向
            if (slow <= cnt) slow = 0;
            else slow -= cnt;
        }
        if(a[qiuck] != '\0') a[slow++] = a[qiuck++];//将非‘#’写入字符串中
    }
    a[slow] = '\0';//手动添加字符串结尾符
}

bool backspaceCompare(char* s, char* t) {
    GetString(s);
    GetString(t);
    int idx = 0;
    /*比较字符串是否相等,可使用库函数,strcmp(char* s, char* t),返回值为0则表示两个字符串相同*/
    while(s[idx] != '\0' && t[idx] != '\0' && s[idx] == t[idx]) idx++;
    if(s[idx] == '\0' && t[idx] == '\0') return true;
    else return false;
}

官方题解中,有个从后向前遍历的方法,绝了,下次再刷这道题时,可以使用该方法。

为什么能用该方法呢?因为,退格符只会对其前面的字符有作用,对其后的字符没有作用。

977. 有序数组的平方

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
/*双指针法,左右指针分别指向数组起始、结束位置。
平方的绝对值最大的一定在数组的两端,所以从两端开始检索*/
int* sortedSquares(int* nums, int numsSize, int* returnSize) {
    int* retarr = (int*)malloc(sizeof(int)*numsSize);
    int idx = numsSize - 1;
    int l = 0, r = numsSize - 1;
    while(l <= r) {
        if (nums[l]*nums[l] >= nums[r]*nums[r]) {
            retarr[idx--] = nums[l]*nums[l];
            l++;
        }
        else {
            retarr[idx--] = nums[r]*nums[r];
            r--;
        }
    }
    *returnSize = numsSize;
    return retarr;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值