代码随想录算法训练营第一天|LeetCode704.二分查找、LeetCode27.移除元素、LeetCode977.有序数组的平方

LeetCode704 二分查找

题目链接:二分查找

左闭右闭写法

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int low = 0;
        int high = nums.size() - 1;
        //左闭右闭
        while(low <= high)
        {
            int middle = (low + high) / 2;
            if(nums[middle] == target)
            {
                return middle;
            }
            else
            {
                if(nums[middle] > target)
                {
                    high = middle - 1;
                }
                else
                {
                    low = middle + 1;
                }
            }
        }
        return -1;
    }
};

左闭右开写法:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int low = 0;
        int high = nums.size();
        //左闭右开
        while(low < high)
        {
            int middle = (low + high) / 2;
            if(nums[middle] == target)
            {
                return middle;
            }
            else
            {
                if(nums[middle] > target)
                {
                    high = middle;
                }
                else
                {
                    low = middle + 1;
                }
            }
        }
        return -1;
    }
};

代码思路: 

二分查找首先要保证数组必须是有序的,其次就是要确认区间的形式,区间也就是代码中的low和high(即数组下标)。其中左闭右闭表示的是判断target是否在[low, high]区间中,而左闭右开是判断target是否在[low, high)区间(即不包含nums[high]的区间)中。根据区间的不同,low和high的初始化以及while的条件都有可能发生改变。

快速判断不同区间对应的low和high的初始值以及while的条件,我们可以假设数组中只有一个元素,也就是只有唯一下标0。

①左闭右闭的情况,即区间为[0, 0],所以low = 0,high = size - 1,可知high = nums.size() - 1,由于low和high的值是可以相等的,可得到while的条件为low<=high。

②左闭右开的情况,即区间为[0, 1),所以low = 0,high = size,可知high = nums.size,由于high是开区间,所以low不可能出现等于high的情况,所以while的条件是low < high

LeetCode27 移除元素

题目链接:移除元素

暴力解法:

时间复杂度: O(N^{2})

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int k = nums.size();
        for(int i = 0; i < k; i++)
        {
            if(nums[i] == val)
            {
                for(int j = i; j < k - 1; j++)
                {
                    nums[j] = nums[j+1];
                }
                i--; // 此处的i--是因为当前位置的值虽然修改为后一个位置的值,但是仍然有可能等于val
                k--;
            }
        }
        return k;
    }
};

暴力解法代码思路:

两层for循环,第一层for循环用来检查当前数组位置的值是否等于val,第二层循环用来移动数组的值,k用来记录移动后的数组的大小。

双指针法:

时间复杂度:O(N)

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int fast = 0;
        int slow = 0;

        while(fast < nums.size())
        {
            if(nums[fast] != val)
            {
                nums[slow] = nums[fast];
                slow++;
            }
            fast++;
        }
        return slow;
    }
};

双指针法代码思路:

双指针法可以看成是一个数组当两个数组使用,其中fast指向的是原数组,slow指向的是经过删减后的新数组,如果原数组对应下标fast的值不等于val,就把nums[fast]的值添加到新数组中,即添加到nums[slow]。

双指针法的本质:新数组赋值

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int fast = 0;//记录nums的当前下标
        int slow = 0;//记录new_nums的当前下标
        vector<int> new_nums(nums.size());
        while(fast < nums.size())
        {
            if(nums[fast] != val)
            {
                new_nums[slow] = nums[fast];//得到不包含val的新数组
                slow++;
            }
            fast++;
        }
        for(int i = 0; i < slow; i++)
        {
            nums[i] = new_nums[i];//将新数组重新赋值给原数组
        }
        return slow;
    }
};

LeetCode977 有序数组的平方

题目链接:有序数组的平方

双指针法:

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int low = 0;
        int high = nums.size() - 1;
        vector<int> result(nums.size());
        int result_loc = nums.size() - 1;   //result数组当前的下标位置
        while(low <= high)
        {
            int low_num = nums[low] * nums[low];
            int high_num = nums[high] * nums[high];
            if(low_num > high_num)
            {
                result[result_loc--] = low_num;
                low++;
            }
            else
            {
                result[result_loc--] = high_num;
                high--;
            }
        }
        return result;
    }
};

代码思路:

由于数组左边可能是负数,所以平方的最大值可能出现在左边或者右边,我们可以左右同时进行平方并比较,然后将大的值先写入新数组result,通过result_loc来记录新数组的下标,result_loc从result数组的最后一个位置开始不断往前移动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值