代码随想录Day 2 | 数组Part 2


Day 1 习题

二分法

昨天对二分法新增的理解包括:左开右闭区间的思路、操作下标的思路。

35. 搜索插入位置

本题较704多了一个插入位置的返回。使用左闭右开的写法,函数返回left或right都可以,因为跳出循环的时候left=right。
另外一种写法是只分为大于和不大于两类,最终都通过区间收窄至1个元素时返回其下标。

    int searchInsert(vector<int>& nums, int target) {
            int left = 0;
            int right = nums.size();
            while (left < right)
            {
                int middle = left + ((right - left) >> 1);
                if (target < nums[middle])
                    left = middle + 1;
                else
                    right = middle;
            }
            return left;
    }

双指针

目前见到的双指针类型有快慢指针和头尾指针。

26. 删除排序数组中的重复项

因为题目要求删除后的数组是有序的,初步考虑头尾指针难以实现。考虑快慢指针的方法,思路和标准题27相同。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int slow = 1;
        int len = nums.size();
        for (int fast = 1; fast < len; fast++)
        {
            if (nums[fast - 1] != nums[fast])
            {
                nums[slow++] = nums[fast];
            }
        }
        return slow;
    }
};

977. 有序数组的平方(双指针)

思路:双指针,申请一个新的数组,左右两指针比较大小后从后向前输入新数组。


209. 长度最小的子数组(滑动窗口)

用单个循环来实现的思路:每一步要么右端点扩展一个元素,要么左端点缩进一个元素。这样写会出现的一个问题是当右指针走到尾部时,如果当前窗口总和仍达不到目标值,则会进入下一次循环,进而造成索引溢出。因此需要额外加上一个判断。

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int left = 0;
        int right = 1;
        int minLength = INT32_MAX;
        if (nums.size() == 0)
            return 0;
        int sum = nums[0];
        while (right <= nums.size()){
            if (sum < target){
                if (right == nums.size()) //如果不加这个判断,则会导致索引溢出
                    break;
                sum += nums[right];
                right++;
            }
            else{
                if  (minLength > right - left)
                    minLength = right - left; //这里可以直接用min(minLength, right-left)
                sum -= nums[left];
                left++; 
            }
        }
        return minLength == INT32_MAX ? 0 : minLength;
        }
};

标准答案中使用双循环,从代码实现结果上来看省去了单循环中繁琐的判断过程。思路是用大循环将右端点视为一个锚点,并在每一步中用小循环将左端点收至最窄,之后再接入下一个右端点。


59. 螺旋矩阵II、 54. 螺旋矩阵

考察对下标的控制。力扣上的方法同网站里给的方法有所不同。


C++语法及特性

  1. 乘方没有运算符,使用pow(x,n);
  2. 初始化一个向量:vector<int> a(len, init_value);
    初始化一个二维矩阵:vector<vector<int>> res(n, vector<int>(n, 0));
  3. 当需要赋一个极大值给某变量时使用 INT32_MAX;

总结

  1. 使用左闭右开的逻辑去判断边界情况,较以往思路更清晰,但仍不熟练,需后续多加练习。
  2. 总感觉还没开窍,可能需要再积累积累做题经验。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值