leetcode刷题 数组 滑动窗口 C++ 20个(剑指offer7 个)

这篇博客主要汇总了LeetCode中关于数组和滑动窗口算法的题目,包括剑指Offer系列和lubuladong的经典题目,如二维数组查找、数组去重、构建乘积数组、滑动窗口最小子串等,详细讲解了各种解题思路和方法。
摘要由CSDN通过智能技术生成

目录

数组(11道):

剑指 Offer 04. 二维数组中的查找

剑指 Offer 39. 数组中出现次数超过一半的数字

剑指 Offer 03. 数组中重复的数字

剑指 Offer 66. 构建乘积数组

lubuladong刷题手把手刷数组题目

167. 两数之和 II - 输入有序数组

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

27. 移除元素

283. 移动零

NSum

1. 两数之和

15. 三数之和

18. 四数之和

lubuladong滑动窗口算法变成了默写题

76. 最小覆盖子串

567. 字符串的排列

438. 找到字符串中所有字母异位词

209. 长度最小的子数组

剑指 Offer 48. 最长不含重复字符的子字符串  3. 无重复字符的最长子串

剑指 Offer 57. 和为s的两个数字 双指针

剑指 Offer 57 - II. 和为s的连续正数序列   滑动窗口 

还没看

给我 O(1) 时间,我能查找/删除数组中的任意元素

啊这,一道数组去重的算法题把东哥整不会了…

二分搜索只能用来查找元素吗?


数组(11道):

剑指 Offer 04. 二维数组中的查找

注意:本题与主站 240 题相同:https://leetcode-cn.com/problems/search-a-2d-matrix-ii/

https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/solution/mian-shi-ti-04-er-wei-shu-zu-zhong-de-cha-zhao-zuo/

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        if(matrix.size()==0) return false;
        int i = matrix.size() - 1, j = 0;
        while(i >= 0 && j < matrix[0].size())
        {
            if(matrix[i][j] > target) i--;
            else if(matrix[i][j] < target) j++;
            else return true;
        }
        return false;
    }
};

剑指 Offer 39. 数组中出现次数超过一半的数字

注意:本题与主站 169 题相同:https://leetcode-cn.com/problems/majority-element/

官方解释五种都不好懂。。。

得看https://cuijiahua.com/blog/2017/12/basis_28.html中的

投票法:数组中有一个数字出现的次数超过数组长度的一半,也就是说它出现的次数比其他所有数字出现次数的和还要多。因此我们可以考虑在遍历数组的时候保存两个值:一个是数组的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1;如果下一个数字和我们之前保存的数字不同,则次数减1。如果次数为零,我们需要保存下一个数字,并把次数设为1。由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把次数设为1时对应的数字。

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        if(nums.empty()){
            return 0;
        }
        // 遍历每个元素,并记录次数;若与前一个元素相同,则次数加1,否则次数减1
        int result = nums[0];
        int times = 1;
        for(int i = 1; i < nums.size(); ++i){
            if(times == 0){
                // 更新result的值为当前元素,并置次数为1
                result = nums[i];
                times = 1;
            }
            else if(nums[i] == result){
                times++;
            }
            else{
                times--;
            }
        }
        
        return result;
    }
};

剑指 Offer 03. 数组中重复的数字

https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/mian-shi-ti-03-shu-zu-zhong-zhong-fu-de-shu-zi-yua/

//方法一:哈希表 
class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        unordered_map<int, int> map;
        for(int num : nums) {
            map[num]++;
            if(map[num]>1) return num;
        }
        //注意返回-1;
        return -1;
    }
};
/*
复杂度分析:
时间复杂度 O(N) : 遍历数组使用 O(N) ,HashSet 添加与查找元素皆为 O(1) 。
空间复杂度 O(N): HashSet 占用 O(N) 大小的额外空间。
*/
方法二:原地交换
class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int i = 0;
        while(i < nums.size()) {
            if(nums[i] == i) {
                i++;
                continue;
            }
            if(nums[nums[i]] == nums[i])
                return nums[i];
            swap(nums[i],nums[nums[i]]);
        }
        return -1;
    }
};

复杂度分析:
时间复杂度 O(N)O: 遍历数组使用 O(N) ,每轮遍历的判断和交换操作使用O(1) 。
空间复杂度 O(1) : 使用常数复杂度的额外空间。

剑指 Offer 66. 构建乘积数组

https://leetcode-cn.com/problems/gou-jian-cheng-ji-shu-zu-lcof/solution/mian-shi-ti-66-gou-jian-cheng-ji-shu-zu-biao-ge-fe/

class Solution {
public:
    vector<int> constructArr(vector<int>& a) {
        int n = a.size();
        // 返回结果的计算
        vector<int> b(n, 1);   
        // 从上到下,左下角的遍历     
        for(int i = 1; i < n; i++){
            b[i] *= b[i-1] * a[i-1];
        }
        // 累计乘积的结果,用于和b[i] 来计算
        int right = 1;
        for(int i=n-2;i>=0;i--){
            right *= a[i+1];
            b[i] *= right;
        }
        return b;
    }
};

lubuladong刷题手把手刷数组题目

167. 两数之和 II - 输入有序数组

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。

函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

说明:

返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

解题思路:双指针,解题思路见代码注释

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int low = 0, high = numbers.size() - 1;
        while (low < high) {
            int sum = numbers[low] + numbers[high];
            if (sum == target) {
                return {low + 1, high + 1};
            } else if (sum < target) {
                ++low;
            } else {
                --high;
            }
        }
        return {-1, -1};
    }
};

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

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值