代码随想录算法训练营day1:数组

代码随想录算法训练营第一天|704.二分查找,24.移除元素

题目链接 -704.二分查找

解答状态:已通过

自己的解答:

class Solution {
public:
    int search(vector<int>& nums, int target) 
    {
        int length = nums.size();
        if(length==0)
        {
            return -1;
        }
        if(length==1)
        {
            if(nums[0]==target)
            {
                return 0;
            }
            else
            {
                return -1;
            }
        }
        int mid = length / 2;
        if(nums[mid]==target)
        {
            return mid;
        }
        else if(nums[mid]>target)
        {
            return divide(0,mid-1,nums,target);
        }
        else if(nums[mid]<target)
        {
            return divide(mid+1,length-1,nums,target);
        }
        else
        {
            return -1;
        }

    }

    int divide(int front,int after,vector<int>& nums,int target)
    {
        if(front==after)
        {
            if(nums[after]==target)
            {
                return after;
            }
            else
            {
                return -1;
            }
        }
        int mid  = (front+after)/2;
        int length = after-front+1;
        if(nums[mid]==target)
        {
            return mid;
        }
        else if(nums[mid]>target)
        {
            return divide(0,mid-1,nums,target);
        }
        else if(nums[mid]<target)
        {
            return divide(mid+1,after,nums,target);
        }
        else
        {
            return -1;
        }

    }
};

解题思路:不知道为什么,自己一开始就想到用递归,首先求出中间元素【mid】,用于与target进行比较,如果正确则直接返回,如果小于target,则在右区间进行求解,相反,在左区间进行求解,当然我的这个方法都是基于题目中提到的两个关键条件:【所有元素是不重复的】和【元素有序】

代码随想录题解:直接用while循环进行搜索,比我的代码要简单一些

左闭右闭

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
        while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=
            int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if (nums[middle] > target) {
                right = middle - 1; // target 在左区间,所以[left, middle - 1]
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,所以[middle + 1, right]
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }
};

左闭右开

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
        while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
            int middle = left + ((right - left) >> 1);
            if (nums[middle] > target) {
                right = middle; // target 在左区间,在[left, middle)中
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,在[middle + 1, right)中
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }
};

[704-代码解析](代码随想录 (programmercarl.com)

[704-视频讲解](手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili)

题目链接-24.移除元素

解答状态:已通过

自己的解答:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) 
    {
        int length = nums.size();
        int pos = 0;
        for(int i=0;i<length;i++)
        {
            if(nums[i]!=val)
            {
                nums[pos] = nums[i];
                pos++;
            }

        }
        return pos;

    }
};

解题思路:因为题目要求移除值为val的元素,那就可以把val值的元素都移到数组尾,非val的元素向前移动,最后返回的pos就是非val元素构成的数组的长度,题目已经说明,超出非val值的部分不用在意

代码随想录题解:

快慢双指针法

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
            if (val != nums[fastIndex]) {
                nums[slowIndex++] = nums[fastIndex];
            }
        }
        return slowIndex;
    }
};

双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

定义快慢指针

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

相向双指针法

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int leftIndex = 0;
        int rightIndex = nums.size() - 1;
        while (leftIndex <= rightIndex) {
            // 找左边等于val的元素
            while (leftIndex <= rightIndex && nums[leftIndex] != val){
                ++leftIndex;
            }
            // 找右边不等于val的元素
            while (leftIndex <= rightIndex && nums[rightIndex] == val) {
                -- rightIndex;
            }
            // 将右边不等于val的元素覆盖左边等于val的元素
            if (leftIndex < rightIndex) {
                nums[leftIndex++] = nums[rightIndex--];
            }
        }
        return leftIndex;   // leftIndex一定指向了最终数组末尾的下一个元素
    }
};

【24-代码解析】

【24-视频讲解】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值