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

Posted 蔚尺丈八声

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码随想录算法训练营第二天 | 977.有序数组的平方209.长度最小的子数组59.螺旋矩阵II相关的知识,希望对你有一定的参考价值。

有序数组的平方

【力扣】977.有序数组的平方

class Solution 
    public int[] sortedSquares(int[] nums) 
        /*
         * 思路:双指针
         * 
         * 参考:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
         *
         * 因为数组含有负数,若是负数的平方有可能大于正数的,所以构造两个指针i和j,
         * 分别指向原数组nums[]的两端,再一个指针k指向所构造新数组result[]的末端,从后往前
         * 依次存入nums[i]的平方和nums[j]的平方的比较结果,哪个大就先存入result[k],然后k
         * 往前移动一格,nums[i]和nums[j]的平方中哪个大的就朝对向移动一格。
         * 
         */

        int result[] = new int[nums.length];
        int i = 0, j = nums.length - 1;
        for (int k = nums.length - 1; k >= 0; k--) 
            int left_square = nums[i] * nums[i];
            int right_square = nums[j] * nums[j];
            if (left_square <= right_square) 
                result[k] = right_square;
                j--;
             else 
                result[k] = left_square;
                i++;
            
        

        return result;
    

    public static void main(String[] args) 
        Solution solution1 = new Solution();
        int nums[] =  -7, -3, 2, 3, 11 ;
        int result[] = solution1.sortedSquares(nums);
        for (int c : result) 
            System.out.println(c);
        
    

长度最小的子数组

【力扣】209.长度最小的子数组

class Solution 
    public int minSubArrayLen(int target, int[] nums) 
        /*
         * 思路:滑动窗口
         * 
         * 参考:
         * 【滑动窗口模板】https://www.bilibili.com/video/BV1V44y1s7zJ/?spm_id_from=333.1007.
         * top_right_bar_window_history.content.click&vd_source=
         * accc6a9ec558fa81b34f121125d4eff0
         * 【动态规划】https://www.bilibili.com/video/BV16G411c7yZ/?spm_id_from=333.788.
         * top_right_bar_window_custom_collection.content.click&vd_source=
         * accc6a9ec558fa81b34f121125d4eff0
         * 【贪心算法】https://blog.csdn.net/effective_coder/article/details/8736718
         * 【滑动窗口解法】https://leetcode.cn/problems/minimum-size-subarray-sum/solutions/
         * 306066/javade-jie-fa-ji-bai-liao-9985de-yong-hu-by-sdwwld/
         * /javade-jie-fa-ji-bai-liao-9985de-yong-hu-by-sdwwld/
         * 【官方题解】https://leetcode.cn/problems/minimum-size-subarray-sum/solutions/305704
         * /chang-du-zui-xiao-de-zi-shu-zu-by-leetcode-solutio/
         * 【前缀和】https://zhuanlan.zhihu.com/p/117569086#:~:text=%E5%89%8D%E7%BC%80%E5%92%
         * 8C%E6%98%AF%E4%B8%80%E7%A7%8D%E9%A2%84%E5%A4%84%E7%90%86%EF%BC%8C%E7%94%A8%E4
         * %BA%8E%E9%99%8D%E4%BD%8E%E6%9F%A5%E8%AF%A2%E6%97%B6%E7%9A%84%E6%97%B6%E9%97%
         * B4%E5%A4%8D%E6%9D%82%E5%BA%A6%E3%80%82%20%E4%B8%BE%E4%B8%AA%E4%BE%8B%E5%AD%90
         * %EF%BC%9A%E7%BB%99%E5%AE%9A%20n,%E4%B8%AA%E6%95%B4%E6%95%B0%EF%BC%8C%E7%84%B6
         * %E5%90%8E%E8%BF%9B%E8%A1%8C%20m%20%E6%AC%A1%E8%AF%A2%E9%97%AE%EF%BC%8C%E6%AF%
         * 8F%E6%AC%A1%E8%AF%A2%E9%97%AE%E6%B1%82%E4%B8%80%E4%B8%AA%E5%8C%BA%E9%97%B4%E5
         * %86%85%E5%80%BC%E7%9A%84%E5%92%8C%E3%80%82
         * 【Arrays.binarySearch 详解】https://blog.csdn.net/londa/article/details/119296502
         * 
         * 滑动窗口算法题应用场景:
         * 关键词:
         * 满足XXX条件(计算结果,出现次数,同时包含)
         * 连续区间
         * 最长/最短
         * 子串/子数组子序列
         * 例如:长度最小的子数组
         * 
         * 滑动窗使用思路(寻找最长)
         * ————核心:左右双指针(L,R)在起始点,R向右逐位滑动循环
         * ————每次滑动过程中
         * 如果:窗内元素满足条件,R向右扩大窗口,并更新最优结果
         * 如果:窗内元素不满足条件,L向右缩小窗口
         * ————R到达结尾
         * 
         * // 最长模板
         * // 初始化left,right,result,bestResult
         * while(右指针没有到结尾)
         * 窗口扩大,加入right对应元素,更新当前result
         * while(result不满足要求)
         * 窗口缩小,移除left对应元素,left右移
         * 
         * 更新最优结果bestResult
         * right++
         * 
         * 返回bestResult
         * 
         * // 最短模板
         * // 初始化left,right,result,bestResult
         * while(右指针没有到结尾)
         * 窗口扩大,加入right对应元素,更新当前result
         * while(result满足要求)
         * 更新最优结果bestResult // 对右指针不设限制,因为条件是result满足要求
         * 窗口缩小,移除left对应元素,left右移
         * 
         * right++
         * 
         * 返回bestResult
         * 
         * 对于本题的解法,可以套用最短模板:
         * 我们把数组中的元素不停的入队,直到总和大于等于s为止,接着记录下队列中元素的个数,
         * 然后再不停的出队,直到队列中元素的和小于s为止(如果不小于s,也要记录下队列中元素的个数,
         * 这个个数其实就是不小于s的连续子数组长度,我们要记录最小的即可)。
         * 接着再把数组中的元素添加到队列中…重复上面的操作,直到数组中的元素全部使用完为止。
         */

        int left = 0, right = 0; // 定义滑动窗口的左右指针
        int result = 0; // 记录滑动窗口的和
        int min_result_len = Integer.MAX_VALUE; // 记录滑动窗口的最小长度
        while (right < nums.length) 
            // 右指针移动,向窗口装入元素
            result += nums[right];
            right++;
            // 右移指针直到满足条件为止,此时进入内循环,才开始移动左指针
            while (result >= target) 
                // 更新最优结果bestResult
                // 子序列长度=右指针-左指针(因为外层循环有个right++,所以不用加1了)
                min_result_len = Math.min(min_result_len, right - left); 
                // 窗口缩小,移除left对应元素,left右移
                result -= nums[left];
                left++;
            
        
        // 如果在nums数组中找不到满足>=target的最小子序列,那么就返回0
        return min_result_len == Integer.MAX_VALUE ? 0 : min_result_len;
    

    public static void main(String[] args) 
        Solution solution1 = new Solution();
        int nums[] =  1,1,1,1,1,1,1,1 ;
        int target = 11;
        int result = solution1.minSubArrayLen(target, nums);
        System.out.println(result);
    


螺旋矩阵II

【力扣】59.螺旋矩阵II

class Solution 
    public int[][] generateMatrix(int n) 
        /*
         * 
         * 思路:模拟元素按顺时针前进的过程即可,注意完成每一行、每一列时,相应缩小边界
         * 
         * 参考:https://leetcode.cn/problems/spiral-matrix-ii/solutions/12594/spiral-matrix-ii-mo-ni-fa-she-ding-bian-jie-qing-x/
         * 
         * 生成一个nxn空矩阵mat,随后模拟整个向内环绕的填入过程:
         * 1、定义当前左右上下边界,r,t,b,初始值num=1,送代终止值tar
         * 2、当num<=tar时,始终按照从左到右、从上到下、从右到左、从下到上填入顺序
         * 循环,每次填入后:
         * 2.1、执行num+=1:得到下一个需要填入的数字;
         * 2.2、更新边界:例如从左到右填完后,上边界t+=1,相当于上边界向内缩1。
         * 3、使用num<=tar而不是t<r||t<b作为迭代条件,是为了解决当n为奇数
         * 时,矩阵中心数字无法在选代过程中被填充的问题。
         * 4、最终返回mat即可。
         * 
         * 
         * 
         */

         int left = 0, right = n - 1, top = 0, bottom = n - 1;
         int nums[][] = new int[n][n]; // 待生成索引的矩阵
         int count = 1; // 记录路线上的元素数
         int x = 0, y = 0; // 表示路线最前面的那个点的坐标,x对应行,y对应列
         nums[x][y] = count; // 记录第一个元素
        //for循环中变量定义成x或y的细节:按照通常的思维,x代表行,y代表列
        //这样,就可以很容易区分出来变化的量应该放在[][]的第一个还是第二个
        //对于变量的边界怎么定义:
            //从左向右填充:填充的列肯定在[left,right]区间
            //从上向下填充:填充的行肯定在[top,bottom]区间
            //从右向左填充:填充的列肯定在[right,left]区间
            //从下向上填充:填充的行肯定在[bootom,top]区间
        //通过上面的总结会发现边界的起始和结束与方向是对应的
         while (count < n * n) 
             // 先从左向右走
             while (y < right) 
                 y++;
                 count++;
                 nums[x][y] = count;
             
             top++; // 缩小上边界
             // 再从上向下走
             while (x < bottom) 
                 x++;
                 count++;
                 nums[x][y] = count;
             
             right--; // 缩小右边界
             // 再从右向左走
             while (y > left) 
                 y--;
                 count++;
                 nums[x][y] = count;
             
             bottom--; // 缩小下边界
             // 再从下向上走
             while (x > top) 
                 x--;
                 count++;
                 nums[x][y] = count;
             
             left++; // 缩小左边界
         
         return nums;
    

    public static void main(String[] args) 
        Solution solution1 = new Solution();
        int nums[][] = solution1.generateMatrix(3);
        for (int c[] : nums) 
            for (int x : c) 
                System.out.println(x);
            
        
    

以上是关于代码随想录算法训练营第二天 | 977.有序数组的平方209.长度最小的子数组59.螺旋矩阵II的主要内容,如果未能解决你的问题,请参考以下文章

代码随想录算法训练营第五十二天 | 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

代码随想录算法训练营第四十二天 | 01背包问题,你该了解这些01背包问题,你该了解这些 滚动数组 416. 分割等和子集

代码随想录算法训练营第六天 | 242.有效的字母异位词349. 两个数组的交集202. 快乐数1. 两数之和

代码随想录算法训练营第六天 | 242.有效的字母异位词349. 两个数组的交集202. 快乐数1. 两数之和

代码随想录算法训练营第三十八天 | 509. 斐波那契数70. 爬楼梯746. 使用最小花费爬楼梯

代码随想录算法训练营第四十九天| 121 买卖股票的最佳时机 122 买卖股票的最佳时机II