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

LeetCode 704 二分查找

题目链接:704
思路:采用二分查找,左右指针用于确定目标所在范围,每次判断范围的中间值是否为目标,若不是则更新范围。
代码:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        // 确定左右边界初始值
        int left = 0;
        int right = nums.size() - 1;
        int i;

        while (left <= right) {
             i = (left + right) / 2;
             // 判断中间值是否为目标
            if (nums[i] == target)
                return i;
            else if (nums[i] > target) 
                // 若中间值大于目标,则移动右指针
                right = i-1;
            else
                // 若中间值小于目标,则移动左指针
                left = i+1;
        }

        return -1;
    }
};

注意:在更新范围时,不应写成right = ileft = i, 否则可能导致死循环。

LeetCode 27 移除元素

题目链接:27

解1:快慢指针

思路:移除元素,也可理解为选出不等于val的元素,并重新写入数组。采用快慢指针,慢指针用于指示下一写入的位置, 快指针用于遍历搜索不等于val的值。为便于理解,可想象有一个新数组,快指针在旧数组中遍历搜索不等于val的值,并依次写入新数组中。只不过,实际实现时,新数组的内存地址与旧数组重合。
代码:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        // pos用于指示下一写入的位置,search用于遍历数组
        int pos = 0;
        int search = 0;

        for (search; search<nums.size(); ++search) {
            // 若search指向的值等于val,则不写入
            // 否则,将该值写入pos指向的位置
            if (nums[search] != val) {
                nums[pos] = nums[search];
                // 若pos处写入值,则pos向后移动,指示下一位置
                ++pos;
            }
        }

        return pos;

    }
};

分析:最坏情况遍历序列2次

解2:双指针优化

思路:通过左右指针,依次将靠右的值赋给靠左的val。左右指针向中心移动直至重合。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int left = 0;
        int right = nums.size() - 1;

        while (left <= right) {
            if (nums[left] == val) {
                // 若左值为val,则将右值赋给左值,并将右指针右移
                // 左指针不动,在下轮中判断新的左值
                nums[left] = nums[right];
                --right;
            } else {
                ++left;
            }
        }

        return left;

    }
};

分析:至多遍历一次

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值