数据结构与算法期末复习第二天

算法部分

二进制求和

原题

给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。

示例 1:

输入:a = "11", b = "1"
输出:"100"
示例 2:

输入:a = "1010", b = "1011"
输出:"10101"
 

提示:

1 <= a.length, b.length <= 104
a 和 b 仅由字符 '0' 或 '1' 组成
字符串如果不是 "0" ,就不含前导零

思路

代码实例

char * addBinary(char * a, char * b){
    int m = strlen(a);
    //strlen用于计算字符串长度
    int n = strlen(b);
    int len = m > n ? m : n;
    //通过比较,选出最长的字符串长度,循环 len 次,从最低位开始遍历。、

    char* str = (char*)malloc(sizeof(char) * (len + 2));
    //使用一个字符串指针str表示上一个位置的进位

    int strTop = 0;
    int add = 0;
    --m, --n;//从高位向低位遍历

    //循环遍历
    while (m >= 0 || n >= 0 || add != 0) {
        int x = m >= 0 ? a[m] - '0' : 0;
        int y = n >= 0 ? b[n] - '0' : 0;
        int sum = x + y + add;
        str[strTop++] = sum % 2 + '0';
        add = sum / 2;
        --m;
        --n;
    }
    
    char* ans = (char*)malloc(sizeof(char) * (strTop + 1));
    //创建一个数组ans,装答案
    
    //进行翻转
    for (int i = strTop - 1; i >= 0; --i) {
        ans[strTop - 1 - i] = str[i];
    }
    ans[strTop] = '\0';
    return ans;
}

移除元素

原题

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}
 

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
 

提示:

0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100

思路

移除我的想法是使用遍历,逐个比较判断是否相等,在比较删除时,定义一个变量进行实时监视,删除就给原数组长度-1,最后返回这个变量

方法一:双指针

方法二:双指针优化

代码实例

方法一:双指针

int removeElement(int* nums, int numsSize, int val) {
    int left = 0;
    for (int right = 0; right < numsSize; right++) {
        if (nums[right] != val) {
            nums[left] = nums[right];
            left++;
        }
    }
    return left;
}

 方法二:双指针优化

int removeElement(int* nums, int numsSize, int val) {
    int left = 0, right = numsSize;
    while (left < right) {
        if (nums[left] == val) {
            nums[left] = nums[right - 1];
            right--;
        } else {
            left++;
        }
    }
    return left;
}

删除有序数组中的重复项

原题

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。

考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:

更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
返回 k 。
判题标准:

系统会用下面的代码来测试你的题解:

int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案

int k = removeDuplicates(nums); // 调用

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被 通过。

示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

提示:

1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 已按 升序 排列

思路

我的思路:已知是个升序数组,故可以再次利用双指针,与前一个数组中的元素比较,如果相等left指针保持不变,如果不同则往下进行

代码实例

int removeDuplicates(int* nums, int numsSize) {
    //因为fast和slow初始化都为1,故需要有与0相比较
    if (numsSize == 0) {
        return 0;
    }
    //初始化定义快慢指针
    int fast = 1, slow = 1;
    while (fast < numsSize) {
        if (nums[fast] != nums[fast - 1]) {
            nums[slow] = nums[fast];
            ++slow;
        }
        ++fast;//快指针也应该往下进行,这是我刚开始没有考虑到的
    }
    return slow;
}

我写的代码

int removeDuplicates(int* nums, int numsSize){
    if(numsSize==0){
        return 0;
    }
    int left=1;
    
    for(int i=1;i<numsSize;i++){
        if(nums[i]!=nums[i-1]){
           
            nums[left]=nums[i];
            left++;
        }
       
    }
    return left;
}

删除有序数组中的重复项 II

原题

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

示例 1:

输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。
示例 2:

输入:nums = [0,0,1,1,1,1,2,3,3]
输出:7, nums = [0,0,1,1,2,3,3]
解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。
 

提示:

1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 已按升序排列

思路

我的思路:判断出现的数组次数是否超过2次,if(nums[i]==nums[i-1])往下走,还是暂定不太确定是否正么进行,前面都是与上一题一样的

代码实例

int removeDuplicates(int* nums, int numsSize) {
    //此次为删除重复超过两次的数组,故numsSize比2小的都无需进行删除操作
    if (numsSize <= 2) {
        return numsSize;
    }
    //初始化定义快慢指针值为2
    int slow = 2, fast = 2;
    //进行判断遍历操作
    while (fast < numsSize) {
        if (nums[slow - 2] != nums[fast]) {//将慢指针的与快指针进行比较
            nums[slow] = nums[fast];
            ++slow;
        }
        ++fast;
    }
    return slow;//很重要,千万别忘返回
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值