代码随想录day2---LeetCode977有序数组的平方&209长度最小的子数组&59螺旋矩阵II
1.LeetCode977有序数组的平方题目链接
- 给你一个按 非递减顺序 排序的整数数组 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] - 分析:粗略想法是找到第一个大于0的位置,然后分别用左右指针往左右遍历,比较大小再加入新数组里,就是实现的时候各种情况都要考虑,写的好像比较冗余,代码如下(java):
点击查看代码
public class Solution {
public int[] sortedSquares(int[] nums) {
int[] result=new int[nums.length];
int j=0;
for(int i=0;i<nums.length;i++){
if(nums[i]<=0){
j++;
}
}
//-3 -2 -1 0 1 2 3
//
int left=j-1;
int right=j;
if(left<0){
for(int i=0;i<nums.length;i++){
result[i]=nums[i]*nums[i];
}
}else if(right>=nums.length){
j=0;
for(int i=nums.length-1;i>=0;i--){
result[j]=nums[i]*nums[i];
j++;
}
}else{
j=0;
while (left>=0||right<nums.length){
if(left<0){
result[j]=nums[right]*nums[right];
right++;
}else if(right>=nums.length){
result[j]=nums[left]*nums[left];
left--;
}else if((nums[left]*nums[left])<(nums[right]*nums[right])){
result[j]=nums[left]*nums[left];
left--;
}else {
result[j]=nums[right]*nums[right];
right++;
}
j++;
}
}
return result;
}
}
- 看完卡哥的视频讲解表示有被自己笑到,想到了双指针,结果没想到从两边取,所以多了那么多的判断是否越界,哈哈哈,练习卡哥双指针法代码如下:
点击查看代码
public class Solution {
public int[] sortedSquares(int[] nums) {
int left=0;
int right=nums.length-1;
int[] result=new int[nums.length];
int i=nums.length-1;
while (left<=right){
if(nums[left]*nums[left]>nums[right]*nums[right]){
result[i]=nums[left]*nums[left];
left++;
}else{
result[i]=nums[right]*nums[right];
right--;
}
i--;
}
return result;
}
}
2.LeetCode209长度最小的子数组题目链接
- 给定一个含有 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 - 分析:题目要找长度最小的>=target的连续子数组,那么可以先找到这个数组中最大的元素所在位置,然后设置左右指针往左右遍历,对了,可以定义一个变量记录target-当前元素后剩余的值,该变量值小于0时停止遍历。
- 结果:写完了没AC,看那个用例的情况我的代码没有考虑到。
- 看视频和文章后,有点脑子懂了手没懂的感觉,暴力破解如下(为了练习,未AC,超时了):
点击查看代码
public class Solution {
public int minSubArrayLen(int target, int[] nums) {
int result=100000;
int tmp=0;
int subLength = 0;
for(int i=0;i<nums.length;i++){
tmp=0;
for(int j=i;j<nums.length;j++){
tmp+=nums[j];
if(tmp>=target){
subLength=j-i+1;
if(subLength<result){
result=subLength;
}
}
}
}
if(result==100000){
result=0;
}
return result;
}
}
- 滑动窗口根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n),代码如下:
点击查看代码
public class Solution {
/**
* 窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。
*
* 窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。
*
* 窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
* @param target
* @param nums
* @return
*/
public int minSubArrayLen(int target, int[] nums) {
int i=0;
int sum=0;
int result=1000000;
int subLength=0;
for(int j=0;j<nums.length;j++){
sum+=nums[j];
while (sum>=target){
subLength=j-i+1;
sum=sum-nums[i];
i++;
if(subLength<result){
result=subLength;
}
}
}
if(result==1000000){
result=0;
}
return result;
}
}
3.LeetCode59螺旋矩阵II 题目链接
-
给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
-
示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]] -
示例 2:
输入:n = 1
输出:[[1]] -
分析:分析了好一会儿,感觉那个螺旋的时候是更新(n,n-1,n-1,n-2,n-2,...,2,2,1,1)个数,不知道有没有用,emmmm...还是不会
-
需要看看视频和文章!看懂了看懂了!保持循环不变量原则,一步一步处理,代码如下:
点击查看代码
public class Solution {
public int[][] generateMatrix(int n) {
int[][] result=new int[n][n];
int startX=0;
int startY=0;
int i,j;
int offset=1;
int circle=n/2;
int num=1;
while (circle>0){
for(j=startY;j<n-offset;j++){
result[startX][j]=num++;
}
for(i=startX;i<n-offset;i++){
result[i][j]=num++;
}
for(;j>startY;j--){
result[i][j]=num++;
}
for (;i>startX;i--){
result[i][j]=num++;
}
startX++;
startY++;
offset++;
circle--;
}
if(n%2==1){
result[n/2][n/2]=num;
}
return result;
}
}