977. 有序数组的平方
给你一个按 非递减顺序 排序的整数数组 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]
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums
已按 非递减顺序 排序
class Solution {
public int[] sortedSquares(int[] nums) {
int length=nums.length-1;
int[] arr=new int[length+1];
int left=0;
int right=length;
while(left<=right){
if(nums[left]*nums[left]<nums[right]*nums[right]){
arr[length--]=nums[right]*nums[right];
right--;
}else{
arr[length--]=nums[left]*nums[left];
left++;
}
}
return arr;
}
}
反思
这道题思路不难,但是要注意的是数组边界的问题。
设置的新数组的长度应该跟原数组的一样长,那么接下来就是双指针的用法,这题需要注意的就是要以非递减,那么我们应该留意数组中是否有负数,如果有负数,应该怎么办。
最主要需要判断的是负数的平方和正数的平方哪个大,这样才好排序。设置两个指针,一个指向原数组的头,一个指向尾,比较头尾两个数平方的大小,大的先插入新数组的尾部,(如果是尾部的大,那么指针左移,如果是头部的大,那么指针右移)。时间复杂度是O(n)
189. 轮转数组
给你一个数组,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
示例 1:
输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
示例 2:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
提示:
1 <= nums.length <= 105
-231 <= nums[i] <= 231 - 1
0 <= k <= 105
思路
将需要移动的k长度数组直接拷贝到临时数组里,再在原数组的基础上,先把length-k个数往后移动k个位置,再从临时数组把数赋到原数组的前k个位置
class Solution {
public void rotate(int[] nums, int k) {
k=k%nums.length;
if(k==0){
return;
}
int[] arr=Arrays.copyOfRange(nums,nums.length-k,nums.length);
for(int i=nums.length-1;i>=k;i--){
nums[i]=nums[i-k];
}
for(int i=0;i<k;i++){
nums[i]=arr[i];
}
}
}
反思
该题思路应该是没问题,但是要在代码实现上踩坑。
在变化原数组时要考虑数组的长度问题,k位置的数要不要包含。
其他的队列等方法可以之后再进行解决
283. 移动零
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
思路
快慢指针:快指针用来处理数据,慢指针用来标记处理好的数据,快指针不断右移,快指针不为0的数赋值给慢指针处,处理完之后将慢指针后面的数值赋0
class Solution {
public void moveZeroes(int[] nums) {
int slow=0;
for(int fast=0;fast<=nums.length-1;fast++){
if(nums[fast]!=0){
nums[slow]=nums[fast];
slow++;
}
}
for(int j=slow;j<=nums.length-1;j++){
nums[j]=0;
}
}
}
反思
关于边界问题
注意数组的最后一个数也要遍历到
167. 两数之和 II - 输入有序数组
给你一个下标从 1 开始的整数数组 numbers
,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target
的两个数。如果设这两个数分别是 numbers[index1]
和 numbers[index2]
,则 1 <= index1 < index2 <= numbers.length
。
以长度为 2 的整数数组 [index1, index2]
的形式返回这两个整数的下标 index1
和 index2
。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
示例 2:
输入:numbers = [2,3,4], target = 6
输出:[1,3]
解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。
示例 3:
输入:numbers = [-1,0], target = -1
输出:[1,2]
解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
提示:
2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers
按 非递减顺序 排列-1000 <= target <= 1000
- 仅存在一个有效答案
思路
双指针的用法,题中给的非递减可以作为参考,如果左右相加大于目标值,右指针左移,如果小于目标值,左指针右移;
最后取下标时一定要记得+1
class Solution {
public int[] twoSum(int[] numbers, int target) {
int l=0;
int r=numbers.length-1;
int[] arr=new int[2];
while(l<=r){
if(numbers[l]+numbers[r]<target){
l++;
}else if(numbers[l]+numbers[r]>target){
r--;
}else{
arr[0]=l+1;
arr[1]=r+1;
return arr;
}
}
return null;
}
}
标签:02,nums,int,示例,力扣,length,数组,指针,刷题
From: https://www.cnblogs.com/wdzx/p/16951339.html