草庐IT

代码随想录算法训练营第二天| 977.有序数组的平方 209.长度最小的子数组 59.螺旋矩阵II

好吃的蛋奶星星 2023-04-10 原文

977.有序数组的平方

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

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

思路1:平方后排序,排序的话第一反应考虑最简单的冒泡排序

class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] NewArry=new int[nums.length];
        for(int i=0;i<nums.length;i++){
            NewArry[i]=nums[i]*nums[i];
        }
        //冒泡排序
        for(int i=0;i<NewArry.length;i++){
            for(int j=i+1;j<NewArry.length;j++){
                if(NewArry[i]>NewArry[j]){
                    int temp=NewArry[j];
                    NewArry[j]=NewArry[i];
                    NewArry[i]=temp;
                }
            }
        }
        return NewArry;
    }
}

平方的过程很简单,遍历数组,给数据进行平方

冒泡排序的基本原理:

  • 比较相邻的元素,如果前一个元素比后一个元素大,则交换位置
  • 对每一对相邻元素做同样的工作,从开始第一对元素到结尾第一对元素,最终最后位置即为最大值。

该思路的缺点,冒泡排序需要双层1for循环,算法时间复杂度为O(N^2),适用于排序数量过少的时候,所以较浪费时间。

思路2:使用双指针

Day1进行过双指针的训练,但是看到这道题还是没有想起如何运用,看了部分解析之后明白了输入数组是有序的,平方之后也可以找到一定的规律,从左边和右边分别出发对比提高效率。

class Solution {
    public int[] sortedSquares(int[] nums) {
        int[] NewArry=new int[nums.length];
        int j=nums.length-1;
        int i=0;
        int index=nums.length-1;
        while(i<=j){
            if(nums[i]*nums[i]<=nums[j]*nums[j]){
                NewArry[index--]=nums[j]*nums[j];
                j--;
            }else{
                NewArry[index--]=nums[i]*nums[i];
                i++;
            }
        }
        return NewArry;
    }
}

定义一个新数组NewArry,和nums数组一样的大小,让index指向NewArry数组终止位置。

如果nums[i]*nums[i]<=nums[j]*nums[j] 那么NewArry[index--]=nums[j]*nums[j],并且让j--

如果nums[i]*nums[i]>nums[j]*nums[j] 那么NewArry[index--]=nums[i]*nums[i],并且让i++

该算法的的时间复杂度为O(n)

209.长度最小的子数组

给定一个含有 n ****个正整数的数组和一个正整数 target **。**找出该数组中满足其和 ****≥ target **的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。**如果不存在符合条件的子数组,返回 0 。

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

该题的思路也是双指针的一个扩展,刚开始做没办法确定结束的指针怎么处理,于是看了解析才有了思路。

滑动窗口:不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。

1、设置左右两个指针

2、又指针遍历数组,并将遍历到的数据相加

若while(sum≥target)(等号的必要性是为了确定最短子序列),移动左指针,并将左指针遍历到的数据减去在进行循环判断

3、最终找到最短子序列

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left=0;
        int sum=0;
        int reslut=Integer.MAX_VALUE;
        for(int right=0;right<nums.length;right++){
            sum+=nums[right];
            while(sum>=target){
                reslut=Math.min(reslut,right-left+1);
                sum-=nums[left];
                left++;
            }
        }
        return reslut==Integer.MAX_VALUE?0:reslut;
    }
}

刚开始不理解reslut=Integer.MAX_VALUE的必要性,到了后续才知道都是为了后续的比较,使用Math.min

59. 螺旋矩阵 II

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

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

这道题看似复杂,但并不需要复杂的推导只需要按照循环逐步去解决

  1. 上侧的从左到右 处理行(start,n-loop);列++
  2. 右侧的从上到下 处理列(start,n-loop); 行++
  3. 下侧的从右到左 处理行(接上侧最后的一列,loop);列—
  4. 左侧的从下到上 处理行(loop,2中最后处理的一行);行—
class Solution {
    public int[][] generateMatrix(int n) {
        int loop=0; //循环次数
        int start=0;
        int[][] NewArray=new int[n][n];
        int i,j;
        int count=1;
        while(loop++<n/2){
            //1.上面从左到右
            for(j=start;j<n-loop;j++){
                NewArray[start][j]=count++;
            }
            //2.右侧从上到下
            for(i=start;i<n-loop;i++){
                NewArray[i][j]=count++;
            }
            //3.下面从右到左
            for(;j>=loop;j--){
                NewArray[i][j]=count++;
            }
            //4.左边从下到上
            for(;i>=loop;i--){
                NewArray[i][j]=count++;
            }
            start++;
        }
        if(n%2==1){
            NewArray[start][start]=count;
        }
        return  NewArray;
    }
}

很多小细节点:

①这里循环次数是0所以一开始就要++

②当n是奇数的时候,最中间会出现一个最终累加的count需要记得添加

③行和列的变化不要搞错,可以画图让自己理清楚

④在循环之外定义了i,j所以1,2步循环结束后i,j是可以保存继续使用到3,4步骤

今日总结:难度比昨天的大了一些,但都是双指针的变形,切记将问题考虑复杂,需要简单化理解和处理,接下来不仅要完成每日题目,还要提高训练速度。

有关代码随想录算法训练营第二天| 977.有序数组的平方 209.长度最小的子数组 59.螺旋矩阵II的更多相关文章

  1. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  5. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  6. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  7. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  8. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  9. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

  10. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

随机推荐