首页 > 编程语言 >代码随想录算法训练营day02 | leetcode 977. 有序数组的平方、35.搜索插入位置、34.在排序数组中查找元素的第一个和最后一个位置、27. 移除元素

代码随想录算法训练营day02 | leetcode 977. 有序数组的平方、35.搜索插入位置、34.在排序数组中查找元素的第一个和最后一个位置、27. 移除元素

时间:2024-02-22 20:00:32浏览次数:24  
标签:target nums int 元素 随想录 ++ vector 数组

题目链接:977. 有序数组的平方-简单

题目描述:

给你一个按 非递减顺序 排序的整数数组 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]

正常解法是平方后直接排序,时间复杂度是 O(n + nlogn)

数组其实是有序的, 只不过负数平方之后可能成为最大数了。

那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。

因此采用双指针法,这里需要创建一个新的数组,这里不能在原数组上进行交换,因为最大值始终在数组的两端,因此判断哪一端的值更大然后将其填充在新数组的末尾,判断完后对应的指针往中间移动。因为是对两端进行判断,所以使用左右两个指针leftright

img

代码如下:

//时间复杂度:O(n)
class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        for(int i = 0; i < nums.size(); ++i)
        {
            nums[i] = nums[i] * nums[i];
        }
        vector<int> ans(nums.size(), 0);
        int left = 0;
        int right = nums.size() - 1;
        int i = nums.size() - 1;
        while(left <= right)
        {
            if(nums[left] > nums[right])
            {
                ans[i] = nums[left];
                ++left;
            }
            else if(nums[left] <= nums[right])
            {
                ans[i] = nums[right];
                --right;
            }
            --i;
        }
        return ans;
    }
};

题目链接:209. 长度最小的子数组-中等

题目描述:给定一个含有 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

方法一:滑动窗口

209.长度最小的子数组

代码如下:

//时间复杂度:O(n)
//空间复杂度:O(1)
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int i = 0; // 滑动窗口起始位置
        int sum = 0; // 滑动窗口数值之和
        int res = 1e9;
        int len = 0; // 滑动窗口的长度
        for(int j = 0; j < nums.size(); ++j)
        {
            sum += nums[j];
            while(sum >= target)
            {
                len = j - i + 1; // 子序列的长度
                res = res < len ? res : len; //更新最小的长度
                sum -= nums[i];
                ++i;
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return res == 1e9 ? 0 : res;
    }
};

方法二:前缀和+二分法

代码如下:

//时间复杂度:O(nlogn)
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        vector<int> sums(nums.size() + 1, 0);
        if (nums.size() == 0) {
            return 0;
        }
        for(int i = 1; i <= nums.size(); ++i)
        {
            sums[i] = sums[i - 1] + nums[i - 1]; // 前缀和
        }
        if(sums[nums.size()] < target) // 所有值加起来小于目标值
            return 0;
        int ans = INT32_MAX;
        for(int j = 1; j < sums.size(); ++j)
        {
            int temp = target + sums[j - 1]; // 前缀和加上目标序列的值
            // 在剩余序列中采用二分法寻找最小的大于等于temp的前缀和
            int left = j;
            int right = sums.size();
            while(left < right)
            {
                int mid = left + ((right - left) >> 1);
                if(sums[mid] >= temp)
                {
                    ans = ans < (mid - j + 1) ? ans : (mid - j + 1);
                    right = mid;
                }
                else
                    left = mid + 1;
            }
            
        }
        return ans == INT32_MAX ? 0 : ans;
    }
};

题目链接:59. 螺旋矩阵 II-中等

题目描述:

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

示例 1:

img

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

示例 2:

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

代码如下:

//时间复杂度 O(n^2): 模拟遍历二维矩阵的时间
//空间复杂度 O(1)
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> mat(n, vector<int>(n, 0)); // 使用vector定义一个二维数组
        int loop = n / 2; // 每个圈循环几次,例如n为奇数3,那么loop = 1 只是循环一圈,矩阵中间的值需要单独处理
        int count = 1;
        int edge = 1; // 边缘厚度,每循环一个圈后厚度+1
        int startx = 0, starty = 0; // 定义每循环一个圈的起始位置
        int i, j;
        while(loop--)
        {
            // 下面开始的四个for就是模拟转了一圈,遵循左开右闭原则
            for(j = starty; j < n - edge; ++j)
            {
                mat[startx][j] = count++;
            }
            for(i = startx; i < n - edge; ++i)
            {
                mat[i][j] = count++;
            }
            for(; j > starty; --j)
            {
                mat[i][j] = count++;
            }
            for(; i > startx; --i)
            {
                mat[i][j] = count++;
            }
            // 第二圈开始的时候,起始位置要各自加1
            ++startx;
            ++starty;
            // 第二圈开始的时候,边缘厚度加1
            ++len;
        }
        // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
        if(n % 2)
        {
            mat[n / 2][n / 2] = n * n;
        }
        return mat;
    }
};

标签:target,nums,int,元素,随想录,++,vector,数组
From: https://www.cnblogs.com/lurk3r/p/18028050

相关文章

  • 代码随想录算法训练营第二十五天| 216.组合总和III 17.电话号码的字母组合
    组合总和III题目链接:216.组合总和III-力扣(LeetCode)思路:仿照昨天的递归模板写的,同样是for循环横向遍历,递归纵向遍历。注意当k>n时要直接跳出,否则会判断栈溢出。额外发现一个问题就是在累加sum时,用for(autoi:path)sum+=path[i];会出现奇怪数字,原因是auto遍历用法错误,正确写......
  • 使用delete和Vue.delete删除数组元素的区别
    JavaScript中的delete运算符可以删除对象的属性,但是它不适用于数组。如果你试图使用delete运算符删除数组中的元素,你会发现该元素的值变为undefined,而数组的长度并没有改变。Vue.js提供了一个名为Vue.delete的方法,它可以帮助我们在删除数组元素时触发响应式更新。与原生JavaScrip......
  • [学习笔记]树状数组
    1.引入树状数组是一种支持单点修改和区间查询的,代码量小的数据结构。(我只看到了代码量小)什么是「单点修改」和「区间查询」?假设有这样一道题:已知一个数列a,你需要进行下面两种操作:「单点修改」:给定\(x,y\),将\(a[x]\)自增$y$。「区间查询」:给定\(l,r\),求解\(a[......
  • day39 动态规划part2 代码随想录算法训练营 63. 不同路径 II
    题目:63.不同路径II我的感悟:题目不难,就是不知道哪个煞笔,把路拦截死了,并且入口就放石头,我真是吐了。理解难点:初始值的遇到障碍要Break其他我写的没错边界考虑:还有入口和出口有障碍物的话,要直接返回0.听课笔记:差不多,考虑的点就是:初始值后面为break开头和结尾有障......
  • 代码随想录算法训练营第二十五天 | 17.电话号码的字母组合 , 216.组合总和III
    216.组合总和III 已解答中等 相关标签相关企业 找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:只使用数字1到9每个数字 最多使用一次返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回......
  • Css中的display属性linline-block(行内区块元素)的详解和应用
    原文链接:https://www.cnblogs.com/lijinwen/p/5679864.html说inline-block(行内区块元素)之前,先说下他另外的2个兄弟display:inline;内联元素,简单来说就是在同一行显示。他没有高度,给内联元素设置width和height是没效果的。display:block;块级元素,简单来说就是就是有换行,会换......
  • 代码随想录算法训练营day 1 | 704 二分查找 27 删除元素
    704二分查找数组基础数组空间地址连续、随机访问时间复杂度O(1)、删除和移动时间复杂度O(n)vector和array区别:vector底层实现为array;array是栈上开辟空间、vector是堆上开辟空间;array不支持迭代器访问,支持指针和索引、vector还支持迭代器访问二分查找适用场景有序数组、数组......
  • JavaScript 的新数组分组方法
    对数组中的项目进行分组,你可能已经做过很多次了。每次都会手动编写一个分组函数,或者使用lodash的groupBy函数。好消息是,JavaScript现在有了分组方法,所以你再也不必这样做了。Object.groupBy和Map.groupBy这两个新方法将使分组变得更简单,并节省我们的时间或依赖性。以前......
  • 代码随想录 day57 最长公共子序列 不相交的线 最大子数组和
    最长公共子序列dp[i][j]:长度为[0,i-1]的字符串text1与长度为[0,j-1]的字符串text2的最长公共子序列为dp[i][j]主要就是两大情况:text1[i-1]与text2[j-1]相同,text1[i-1]与text2[j-1]不相同如果text1[i-1]与text2[j-1]相同,那么找到了一个公共元素,所以dp......
  • day38 动态规划part1 代码随想录算法训练营 746. 使用最小花费爬楼梯
    题目:746.使用最小花费爬楼梯我的感悟:哈哈,我居然自己独立写出来了,确实,只要定义定清楚了,哪怕定的含义只有自己能看懂,只要定义一致就可以求出解决来!!!我真是个大天才!!理解难点:听课笔记:代码示例:classSolution:defminCostClimbingStairs(self,cost:List[int])->int:......