977.有序数组的平方
题目链接:977. 有序数组的平方 - 力扣(LeetCode)
题目
给你一个按 非递减顺序 排序的整数数组 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 + n * logn)
双指针法:
题目中数组是有序的,同时负数开平方以后可能会变成最大数。由此可以得出数组的平方的最大值只可能在数组的左右两端。
因此可以采用双指针法,一个左指针在数组最左端 ( left = 0),一个右指针在数组最右端 ( right = 0) ,两边平方进行比较,较大的赋值到新数组的末尾,同时相应的指针移动。
时间复杂度: O(n)
代码
暴力法:略
双指针法:
1 class Solution { 2 public int[] sortedSquares(int[] nums) { 3 int[] result = new int[nums.length]; 4 int left = 0; // 左指针 5 int right = nums.length - 1; // 右指针 6 int index = nums.length - 1; // 当前新数组的索引位置 7 while(left <= right){ // 注意这里要left <= right,因为最后要处理两个元素 8 if(nums[left] * nums[left] > nums[right] * nums[right]){ 9 result[index--] = nums[left] * nums[left]; 10 ++left; 11 }else{ 12 result[index--] = nums[right] * nums[right]; 13 --right; 14 } 15 } 16 return result; 17 } 18 }
209.长度最小的子数组
题目链接:209. 长度最小的子数组 - 力扣(LeetCode)
题目
给定一个含有 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
思路
暴力法:
通过两个for不断寻找条件符合的子序列。
时间复杂度: O(n ^ 2)
滑动窗口:
首先确认三点:
- 窗口内是什么?(满足其和 ≥ target 的长度最小的 连续 子数组。)
- 如何移动窗口的起始位置?(如果当前窗口的值大于target 了,窗口就要向前移动了(也就是该缩小了)。)
- 如何移动窗口的结束位置?(窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。)
先记录前面几个元素的和,当满足大于等于target时,就开始缩减窗口大小直到小于target,记录此时极限的窗口大小。
时间复杂度: O(n)
代码
暴力法:
1 class Solution { 2 public int minSubArrayLen(int target, int[] nums) { 3 int result = Integer.MAX_VALUE; // 最终的结果 4 int sum = 0; // 子序列的数值之和 5 int subLength = 0; // 子序列的长度 6 for (int i = 0; i < nums.length; i++) { // 设置子序列起点为i 7 sum = 0; 8 for (int j = i; j < nums.length; j++) { // 设置子序列终止位置为j 9 sum += nums[j]; 10 if (sum >= target) { // 一旦发现子序列和超过了s,更新result 11 subLength = j - i + 1; // 取子序列的长度 12 result = result < subLength ? result : subLength; 13 break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break 14 } 15 } 16 } 17 // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列 18 return result == Integer.MAX_VALUE ? 0 : result; 19 } 20 }
滑动窗口:
1 class Solution { 2 public int minSubArrayLen(int target, int[] nums) { 3 int result = Integer.MAX_VALUE; 4 int start = 0; // 滑动窗口起始位置 5 int sum = 0; // 滑动窗口数值之和 6 7 for(int end = 0;end < nums.length;end++){ 8 sum += nums[end]; 9 // 当sum > target 时开始滑动窗口更新 10 while(sum >= target){ 11 int subLength = end - start + 1; // 当前滑动窗口的长度 12 result = result > subLength ? subLength : result; 13 sum -= nums[start++]; // 变更起始位置 14 } 15 } 16 //如果结果还是初始说明不存在符合条件的子数组,则返回0. 17 return result == Integer.MAX_VALUE ? 0 : result; 18 } 19 }
59.螺旋矩阵II
题目链接:59. 螺旋矩阵 II - 力扣(LeetCode)
题目
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
示例 1:
输入:n = 3 输出:[[1,2,3],[8,9,4],[7,6,5]]
示例 2:
输入:n = 1 输出:[[1]]
思路
模拟顺时针画矩阵的过程:
- 填充上行从左到右
- 填充右列从上到下
- 填充下行从右到左
- 填充左列从下到上
注意:
- n/2即为要走的圈数
- 到第二圈后 起始点变为(1,1),以此类推
- n为奇数的时候,中心点单独赋值
- 画边时,左闭右开
代码:
1 class Solution { 2 public int[][] generateMatrix(int n) { 3 int loop = 0; // 控制循环次数 4 int[][] res = new int[n][n]; 5 int start = 0; // 每次循环的起始点(start, start) 6 int count = 1; // 定义填充数字 7 int i, j; // i 代表行,j 代表列 8 9 while (loop++ < n / 2) { // 判断边界后,loop从1开始 10 // 模拟上侧从左到右,注意 此时 loop = 1 11 for (j = start; j < n - loop; j++) { 12 res[start][j] = count++; 13 } 14 15 // 模拟右侧从上到下 16 for (i = start; i < n - loop; i++) { 17 res[i][j] = count++; 18 } 19 20 // 模拟下侧从右到左 21 for (; j >= loop; j--) { 22 res[i][j] = count++; 23 } 24 25 // 模拟左侧从下到上 26 for (; i >= loop; i--) { 27 res[i][j] = count++; 28 } 29 30 //更新下次起始点 31 start++; 32 } 33 // n 为奇数时,中心值单独赋值 34 if (n % 2 == 1) { 35 res[start][start] = count; 36 } 37 return res; 38 } 39 }
标签:977,target,nums,int,随想录,++,result,数组 From: https://www.cnblogs.com/xpp3/p/17087621.html