【LeetCode】-数组

文章目录

前言

初识LeetCode与算法,将在此系列文章里面,记录自己的算法学习经历,前期主要是监督自己学习打卡,后期我会将自己对知识的理解,慢慢补充到文章当中,希望大家能在阅读我的文章中,有所收获。该系列文章的刷题顺序以代码随想录为线索。

一、二分查找

题目:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

提示:

你可以假设 nums 中的所有元素是不重复的。
n 将在 [1, 10000]之间。
nums 的每个元素都将在 [-9999, 9999]之间。

来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/binary-search

思路:
1、选择区间,选择是左闭右闭或者左闭右开,这个是代码的核心。
2、用到while、if-else if-else知识点

代码:

# 选择左闭右闭区间

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

二、移除元素

题目:
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

示例 1:

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

示例 2:

输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

提示:

0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100

来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/binary-search

思路:
1、写两个for循环,第一个for循环用来遍历,第二个for循环用来移动元素
2、双指针法,第一个快指针用来遍历,第二个慢指针用来指向数组下标

代码:

#双指针法
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slowIndex = 0;
        int fastIndex = 0;
        int size = nums.size();
        for(fastIndex = 0; fastIndex < size ; fastIndex++)
        {
            if(val != nums[fastIndex])
            {
                nums[slowIndex++] = nums[fastIndex];
            }
        }
        return slowIndex;

    }
};

三、有序数组的平方

题目:
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:

输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

示例 2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

提示:

1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 已按 非递减顺序 排序

来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/binary-search

思路:
1、直接将每个数组中的元素平方,之后再进行排序操作(直接掉用sort方法)
2、双指针法

代码:

#双指针法

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

    }
};

四、长度最小的子数组

题目:
给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例 2:

输入:target = 4, nums = [1,4,4]
输出:1

示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

提示:

1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105

来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/binary-search

思路:
1、使用两个for循环,第一个循环用来遍历,第二个循环用来判断
2、滑动窗口法,使用两个指针,用一个循环来完成两个循环的作用。

代码:

#暴力解法

class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX;
        int sum = 0;
        int subLength = 0;
        for(int i = 0; i<nums.size(); i++)
        {
            sum = 0;
            for(int j = i; j<nums.size(); j++)
            {
                sum +=nums[j];
                if(sum > target)
                {
                    subLength = j - i + 1;
                    result = result < subLength ? result : subLength;
                    break;
                }

            }
        }
        return result == INT32_MAX ? 0 : result;

    }
};



#滑动窗口法
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int result = INT32_MAX;
        int sum = 0;
        int j = 0;
        int subLength = 0;
        for(int i = 0; i<nums.size(); i++)
        {
            sum +=nums[i];
            while(sum >= target)   //这里是大于等于
            {
                subLength = i - j + 1;
                result = result < subLength ? result : subLength;
                sum -=nums[j++];
            }
        }
        return result == INT32_MAX ? 0 : result;

    }
};

五、螺旋矩阵 II

题目:
给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

示例 1:

输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]]

示例 2:

输入:n = 1
输出:[[1]]

提示:

1 <= n <= 20

来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/binary-search

思路:
1、如何将此类问题建模是一个难点!

代码:

class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> res(n, vector<int>(n,0));
        int startx = 0, starty = 0;
        int loop = n/2;
        int mid = n/2;
        int count = 1;
        int offset = 1;
        int i,j;
        while(loop--)
        {   
            i = startx;
            j = starty; 
            for( j = starty; j < starty + n - offset; j++)
            {
                res[startx][j] = count++;
            }

            for( i = startx; i < startx + n - offset; i++)
            {
                res[i][j] = count++;                
            }

            for( ; j > starty; j--)
            {
                res[i][j] = count++;    
            }

            for( ; i > startx; i--)
            {
                res[i][j] = count++;
            }

            startx++;
            starty++;

            offset +=2;
        }
        if(n%2)
        {
            res[mid][mid] = count;
        }

        return res;
        

    }
};

知识点补充

1、for循环知识,for循环语句中for()里面的条件判断:
【LeetCode】-数组2、vector容器和数组的区别:
vector可以理解为动态数组,数组理解为静态数组。
动态数组,即可以动态扩展,字面意思就是在原本数组后面再添加新的元素。但是需要注意的是:动态扩展并不是在原本的内存空间中扩展,而是将原来的数据拷贝到更大的内存空间中,同时释放原来的内存空间。
3、

上一篇:mysql小计合计


下一篇:夺命雷公狗-----React---9--map数据的遍历