阿里云网站建设的功能,培训美工设计师,php7.3 wordpress,下载wordpress 5.2.2977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums#xff0c;返回 每个数字的平方 组成的新数组#xff0c;要求也按 非递减顺序 排序。 输入#xff1a;nums [-4,-1,0,3,10] 输出#xff1a;[0,1,9,16,100] 解释#xff1a;平方后#xff0c;数组变为 […977.有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums返回 每个数字的平方 组成的新数组要求也按 非递减顺序 排序。 输入nums [-4,-1,0,3,10] 输出[0,1,9,16,100] 解释平方后数组变为 [16,1,0,9,100] 排序后数组变为 [0,1,9,16,100] 输入nums [-7,-3,2,3,11]
输出[4,9,9,49,121] 解法1当然是暴力咯
C版本注意冒泡排序过不了用快排吧
class Solution {
public:vectorint sortedSquares(vectorint nums) {for(int i 0; inums.size();i){nums[i] nums[i]*nums[i];}// return maoPaoSort(nums);sort(nums.begin(),nums.end());return nums;}// vectorint maoPaoSort(vectorint nums) { //冒泡排序 // for(int i 0; inums.size();i){// for(int j i; jnums.size(); j){// if(nums[i]nums[j]){// int temp 0;// temp nums[i];// nums[i] nums[j];// nums[j] temp;// }// }// }// return nums;// }};
Python版本
class Solution:def sortedSquares(self, nums: List[int]) - List[int]:nums [i**2 for i in nums]nums.sort()return nums
解法2双指针法 数组其实是有序的 那么数组平方的最大值就在数组的两端不是最左边就是最右边不可能是中间。此时可以考虑双指针法了i指向起始位置j指向终止位置。比较平方后的大小存入到result中。
C版本
class Solution {
public:vectorint sortedSquares(vectorint nums) {vectorint result;for(int i 0, j nums.size()-1; i j;){if (nums[i]*nums[i] nums[j]*nums[j]){result.push_back(nums[j]*nums[j]);j--;}else{result.push_back(nums[i]*nums[i]);i;}}reverse(result.begin(),result.end()); // 反转return result;}
};
Python版本
class Solution:def sortedSquares(self, nums: List[int]) - List[int]:result []i 0j len(nums)-1while(ij):if(nums[i]**2nums[j]**2):result.append(nums[j]**2)j - 1else:result.append(nums[i]**2)i 1result.reverse()return result
209.长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, ..., numsr-1, numsr] 并返回其长度。如果不存在符合条件的子数组返回 0 。 输入target 7, nums [2,3,1,2,4,3]
输出2
解释子数组 [4,3]是该条件下的长度最小的子数组。 解法一暴力解决两层for循环不断更新子数组的长度写了半天超时了。
class Solution {
public:int minSubArrayLen(int target, vectorint nums) {int result INT32_MAX;for(int i 0; inums.size(); i){int subArrLength 1;int currentNum nums[i];// cout nums[i] endl;if(currentNumtarget){return 1;}else{for(int j i 1; jnums.size();){subArrLength;currentNum currentNum nums[j];// cout nums[j] endl;if (currentNumtarget){j;}else{result resultsubArrLength ? result : subArrLength;// cout subArrLengthsubArrLength endl;break;}}}}return result INT32_MAX ? 0 : result;}
};
解法二滑动窗口 在本题中实现滑动窗口主要确定如下三点
窗口内是什么如何移动窗口的起始位置如何移动窗口的结束位置
窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
窗口的起始位置如何移动如果当前窗口的值大于s了窗口就要向前移动了也就是该缩小了。窗口的结束位置如何移动窗口的结束位置就是遍历数组的指针也就是for循环里的索引。 滑动窗口本质是满足了单调性,即左右指针只会往一个方向走且不会回头。收缩的本质即去掉不再需要的元素。也就是做题我们可以先固定移动右指针判断条件是否可以收缩左指针算范围。大家可以好好理解一下。加入滑动窗口中有负数怎么办 如果有负数的话感觉也不能用滑动窗口了因为有负数的话无论你收缩还是扩张窗口你里面的值的总和都可能增加或减少就不像之前收缩一定变小扩张一定变大一切就变得不可控了。如果要 cover 所有的情况那每次 left 都要缩到 right那就退化为暴力了哈哈。在滑动窗口类型题目里有没有去DEBUG的什么小技巧呢 一般是怀疑哪里有问题就打印哪里 像今天的滑动窗口 就可以把窗口首尾的下标变化过程打印出来 能很清楚的看到窗口是怎样移动的双指针和滑动窗口有什么区别感觉双指针也是不断缩小的窗口。这道题我想用两头取值的双指针结果错了 因为两头指针走完相当于最多只把整个数组遍历一遍会漏掉很多情况。滑动窗口实际上是双层遍历的优化版本而双指针其实只有一层遍历只不过是从头尾开始遍历的。 滑动窗口的原理是右边先开始走然后直到窗口内值的总和大于target此时就开始缩圈缩圈是为了找到最小值只要此时总和还大于target我就一直缩小缩小到小于target为止在这过程中不断更新最小的长度值然后右边继续走如此反复直到右边碰到边界。这样就保证了可以考虑到最小的情况其实本题就是利用双指针来实现滑动窗口的收缩与扩张实质还是双指针的解题思想。
C版本
class Solution {
public:int minSubArrayLen(int target, vectorint nums) {int result INT32_MAX;int i 0;int currentNum 0;int subArrLength 0;for(int j 0; jnums.size(); j){currentNum nums[j];while(currentNum target){ // 如多当前累加值大于目标值subArrLength j - i 1; //滑动窗口的长度result resultsubArrLength?result:subArrLength;currentNum - nums[i]; //收缩窗口}}return result INT32_MAX ? 0 : result;}
};
Python版本
class Solution:def minSubArrayLen(self, target: int, nums: List[int]) - int:result float(inf)currentNum 0i 0subArrLength 0for j in range(len(nums)):currentNum nums[j]while(currentNum target):subArrLength j - i 1result min(subArrLength,result)currentNum - nums[i]i 1return 0 if result float(inf) else result
59.螺旋矩阵II
给定一个正整数 n生成一个包含 1 到 n^2 所有元素且元素按顺时针顺序螺旋排列的正方形矩阵。 示例:
输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 纯纯一个模拟题。
class Solution {
public:vectorvectorint generateMatrix(int n) {vectorvectorint res(n, vectorint(n, 0)); // 使用vector定义一个二维数组int startx 0, starty 0; // 定义每循环一个圈的起始位置int loop n / 2; // 每个圈循环几次例如n为奇数3那么loop 1 只是循环一圈矩阵中间的值需要单独处理int mid n / 2; // 矩阵中间的位置例如n为3 中间的位置就是(11)n为5中间位置为(2, 2)int count 1; // 用来给矩阵中每一个空格赋值int offset 1; // 需要控制每一条边遍历的长度每次循环右边界收缩一位int i,j;while (loop --) {i startx;j starty;// 下面开始的四个for就是模拟转了一圈// 模拟填充上行从左到右(左闭右开)for (j starty; j n - offset; j) {res[startx][j] count;}// 模拟填充右列从上到下(左闭右开)for (i startx; i n - offset; i) {res[i][j] count;}// 模拟填充下行从右到左(左闭右开)for (; j starty; j--) {res[i][j] count;}// 模拟填充左列从下到上(左闭右开)for (; i startx; i--) {res[i][j] count;}// 第二圈开始的时候起始位置要各自加1 例如第一圈起始位置是(0, 0)第二圈起始位置是(1, 1)startx;starty;// offset 控制每一圈里每一条边遍历的长度offset 1;}// 如果n为奇数的话需要单独给矩阵最中间的位置赋值if (n % 2) {res[mid][mid] count;}return res;}
};
代码直接抄 再看看学习下吧 之后再写。 总结
再多看看滑动窗口和螺旋矩阵这个题吧