【leetcode】数组刷题记录

【leetcode】数组刷题记录


前言

本文是基于leetcode数组例题的学习记录

704. 二分查找

复习一下二分

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int l = 0, r = nums.size() - 1;
        while(l < r)
        {
            int mid = l + r + 1 >> 1;
            if(nums[mid] <= target)l = mid;
            else r = mid - 1;
        }
        return nums[l] == target ? l : -1;
    }
};

这里有一个重要点,当是l = mid的时候,mid需要等于l + r + 1。如果是l = mid + 1,mid就等于l + r。我也不记得为什么了,当初就是这么背的~
贴个模板:
链接
版本1
当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。

C++ 代码模板:

int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}

版本2
当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。

C++ 代码模板:

int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

27. 移除元素

链接
这应该算最简洁的吧~

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

977. 有序数组的平方

链接
先来个暴力

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        for (int i = 0; i < nums.size(); i++)
        {
            nums[i] *= nums[i];
        }
        sort(nums.begin(), nums.end());
        return nums;
    }
};

再来个双指针(数组题目常用做法)

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int k = nums.size() - 1;
        vector<int> res(nums.size());
        int i = 0, j = nums.size() - 1;
        while(i <= j)
        {
            if (nums[i] * nums[i] < nums[j] * nums[j])  
            {
                res[k--] = nums[j] * nums[j];
                j--;
            }
            else 
            {
                res[k--] = nums[i] * nums[i];
                i++;
            }
        }
        return res;
    }
};

209. 长度最小的子数组

链接
跟上题一样,碰到数组想双指针(其实是滑动窗口,但这种也算是用两个变量去表示了)

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int l = 0;
        int r = 0;
        int cursum = 0;
        int minlength = 0;
        while(r <= nums.size()-1)
        {
            cursum += nums[r];
            while(cursum >= target)
            {
                if(minlength >= r - l + 1 || minlength == 0)
                minlength = r - l + 1; 
                cursum -= nums[l];
                l++;
            }
            r++;
        }
        return minlength;
    }
};

59. 螺旋矩阵 II

链接
很烂的写法:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        int offset = 0;
        int num = 1;
        vector<vector<int>> ans(n, vector<int> (n));
        while(1)
        {
            for(int i = offset; i < n - offset; i ++ )
            {
                ans[offset][i] = num ++;
                if(num > n * n)break;
            }
            if(num > n * n)break;
            for(int i = offset + 1; i < n - offset; i ++ )
            {
                ans[i][n - offset - 1] = num ++;
                if(num > n * n)break;
            }
            if(num > n * n)break;
            for(int i = n - offset - 2; i >= offset; i -- )
            {
                ans[n - offset - 1][i] = num ++;
                if(num > n * n)break;
            }
            if(num > n * n)break;
            for(int i = n - offset - 2; i > offset; i -- )
            {
                ans[i][offset] = num ++;
                if(num > n * n)break;
            }
            if(num > n * n)break;
            offset ++;
        }
        return ans;
    }
};

看了题解再写一遍

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        int l = 0, r = n - 1, t = 0, b = n - 1;
        vector<vector<int>> ans(n, vector<int> (n));
        int num = 1, tar = n * n;
        while(num <= tar)
        {
            for(int i = l; i <= r; i++) ans[t][i] = num++;
            t++;
            for(int i = t; i <= b; i++) ans[i][r] = num++;
            r--;
            for(int i = r; i >= l; i--) ans[b][i] = num++;
            b--;
            for(int i = b; i >= t; i--) ans[i][l] = num++;
            l++;
        }
        return ans;
    }
};

LCR 160. 数据流中的中位数

链接
这是比较特别的一道题,没写出来,看看题解了解一下小顶堆和大顶堆的做法
题解

class MedianFinder {
public:
    priority_queue<int, vector<int>, greater<int>> A; // 小顶堆,保存较大的一半
    priority_queue<int, vector<int>, less<int>> B; // 大顶堆,保存较小的一半
    MedianFinder() { }
    void addNum(int num) {
        if(A.size() != B.size()) {
            A.push(num);
            B.push(A.top());
            A.pop();
        } else {
            B.push(num);
            A.push(B.top());
            B.pop();
        }
    }
    double findMedian() {
        return A.size() != B.size() ? A.top() : (A.top() + B.top()) / 2.0;
    }
};

总结

数组:总结篇
大多数数组题目无非就是用 二分、双指针、滑动窗口、模拟、前缀和的方式去做

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值