day1-704. 二分查找 27. 移除元素(C++)

今天是参加代码随想录的第一天,原来都是使用c语言,也用过一点点java,没有接触过c++,但这次我选择使用c++(单纯喜欢),开头就遇到了一些问题

开始前的准备

今天的题目与数组相关,为了方便调试,我计划在visual studio中使用主函数调用class Solution,但出现了问题

辗转多地解决,原因是没有在开头加上“using namespace std;”,加上后解决问题

第一题-704. 二分查找

主函数

用于自己测试代码运行结果是否正确

int main() {
    Solution solution;
    vector<int> nums={ -1,0,3,5,9,12};
    int target = 2;
    int result = solution.search(nums, target);

    if (result != -1) {
        cout << "目标 " << target << " 在数组中的位置是: " << result << endl;
    }
    else {
        cout << "目标 " << target << " 不在数组中。" <<endl;
    }
    return 0;
}

解决方法一——左闭右闭

左闭右闭即【left,right】

class Solution {
public:
    //左闭右闭
    int search(vector<int>& nums, int target) {
        int len = nums.size();//数组长度
        int left = 0, right = len - 1;
        int mid;
        //循环--当左边界<=右边界时
        //左闭右闭可以取等号
        while (left<=right) {
            mid = (left + right) / 2;
            //目标在左边
            if (target < nums[mid]) {
                //右闭,mid的值不在范围内,因此减一
                right = mid - 1;
            }
            //目标在右边
            else if (target > nums[mid]) {
                //左闭,mid的值不在范围内,因此加一
                left = mid + 1;
            }
            //找到目标所在数组位置-mid
            else {
                return mid;
            }
        }
        //没找到
        return -1;
    }
};

运行结果

解决方法二——左闭右开

左开右开即【left,right)

class Solution {
public:
    //左闭右开
    int search(vector<int>& nums, int target) {
        int len = nums.size();//数组长度
        //取不到right因此可以等于len
        int left = 0, right = len;
        int mid;
        //循环--当左边界<右边界时
        //左闭右开不可以取等号
        while (left<right) {
            mid = (left + right) / 2;
            //目标在左边
            if (target < nums[mid]) {
                //右开,mid的值不在范围内
                right = mid;
            }
            //目标在右边
            else if (target > nums[mid]) {
                //左闭,mid的值不在范围内,因此加一
                left = mid + 1;
            }
            //找到目标所在数组位置-mid
            else {
                return mid;
            }
        }
        //没找到
        return -1;
    }
};

运行结果

第二题- 27. 移除元素

解决方法一——暴力解

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        //两层暴力解法
        int count = nums.size();
        for (int i = 0; i < count; ) {
            //不是被删除的元素
            if (nums[i] != val) {
                i++;
            }
            //是被删除的元素
            else {
                int del = i;
                count--;
                for (int j = i + 1; j < nums.size(); j++) {
                    nums[del++] = nums[j];
                }
            }
        }
        return count;
    }
};

运行结果

【重难】解决方法二——双指针法

这部分是今天的难点,花了较长时间理解,双指针是使用一个快指针和一个慢指针在一个for循环下完成两个for循环的工作。

  • 快指针:寻找新数组的元素 ,新数组就是不含有需要被删除元素的数组
  • 慢指针:指向更新,新数组下标的位置

简单来说,快指针遇到新数组的元素会把元素的值赋给慢指针所在的位置,快指针遇到需要被删除的元素会前进1,再继续操作,需要注意的是,快指针会遍历完整个原始数组,慢指针不会

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        //快慢指针都从头开始
        int fast=0, slow=0;
        for (fast = 0; fast < nums.size(); fast++) {
            //当前元素不是要被删除的元素,赋值
            if (nums[fast] != val) {
                nums[slow] = nums[fast];
                slow++;
            }
            //当前元素需要被删除时仅需要fast+1操作,在for循环里
        }
        return slow;
    }
};

运行结果

总结

今天的训练结束啦,大概花费3-4h,由于是第一天,在选择看视频,看文章,做题三件事情的顺序上有一些纠结,由于同样一个题有多种解法,比如第一题,可以直接遍历求解(虽然不太明智,但也能解决),所以我认为第一次做可以先看视频了解一下这道题的优解,再自己写代码实现,会增加解题的效率。

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值