有序数组的平方
数组 有序 平方
2023-09-11 14:19:04 时间
给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。
示例 1:
输入:[-4,-1,0,3,10]
输出:[0,1,9,16,100]
示例 2:
输入:[-7,-3,2,3,11]
输出:[4,9,9,49,121]
大致看了下该题在力扣的评论,先平方,然后再sort的解题代码还很多。其实这应该不是本题的题意,要不然没必要强调是非递减顺序排序
。在这里三种情况:纯正数数组,纯负数数组,正负混合的数组。
对于纯正数数组直接代码如下:
int length = A.length;
int res[] = new int[length];
//都是正数,含0
if(A[0]>=0) {
for(int i=0;i<length;i++) {
res[i]= (int) Math.pow(A[i], 2);
}
return res;
}
对于纯负数数组,算法也很简单:
int length = A.length;
int res[] = new int[length];
//都是负数,含0
if(A[length-1]<=0) {
System.out.print( "0000 ");
int index = length-1;
for(int i=0;i<length;i++) {
res[index--]= (int) Math.pow(A[i], 2);
}
return res;
}
那么本体的考点应该就是第三种情况的算法,即正负混合的数组怎么解答本题。
其实解题思想也很简单:因为是原数组是非递减顺序排序的,比如[-4,-1,0,3,10],那么平方过后就是[16,1,0,9,100].
如果都是正数的话,那么最右边的数肯定是最大的,其平方也是最大的,但是包含了负数的话,平方后谁大那就说不定了。所以在这里采用了双指针法,从两边逐次对比,谁大取谁:
int left = 0, right = length - 1;
int resIndex = length - 1;
while (resIndex >= 0) {
int leftSquare = (int) Math.pow(A[left], 2);
int rightSquare = (int) Math.pow(A[right], 2);
if (leftSquare >= rightSquare) {
res[resIndex] = leftSquare;
left++;
} else {
res[resIndex] = rightSquare;
right--;
}
resIndex--;
}
return res;
完整的算法如下:
public static int[] sortedSquares2(int[] A) {
int length = A.length;
int res[] = new int[length];
//说明都是正数
if(A[0]>=0) {
for(int i=0;i<length;i++) {
res[i]= (int) Math.pow(A[i], 2);
}
return res;
}
//都是负数
if(A[length-1]<=0) {
int index = 0;
for(int i=0;i<length;i++) {
res[index++]= (int) Math.pow(A[i], 2);
}
return res;
}
//正负都有的情况
int left = 0, right = length - 1;
int resIndex = length - 1;
while (resIndex >= 0) {
int leftSquare = (int) Math.pow(A[left], 2);
int rightSquare = (int) Math.pow(A[right], 2);
// 将最大值放在后面
if (leftSquare >= rightSquare) {
res[resIndex] = leftSquare;
left++;
} else {
res[resIndex] = rightSquare;
right--;
}
resIndex--;
}
return res;
}
但是对于第三种,其效率还可以做一个小小的优化,因为在left或者right的值没有变换的情况下会造成leftSquare或者rightSquare 平方的重复运算,可以小小修改一下:
int left = 0, right = length - 1;
int resIndex = length - 1;
//在while循环外计算一次
int leftSquare = (int) Math.pow(A[left], 2);
int rightSquare = (int) Math.pow(A[right], 2);
//判断是左边的数据大还是右边的数据大
boolean fromLeft = false;
while (resIndex >= 0) {
//谁大取谁
if (leftSquare >= rightSquare) {
res[resIndex] = leftSquare;
left++;
fromLeft = true;
} else {
res[resIndex] = rightSquare;
right--;
fromLeft = false;
}
resIndex--;
//防止数组越界
if(left>length-1) {
break;
}
//防止重复对leftSquare或者rightSquare 计算
if (fromLeft) {
leftSquare = (int) Math.pow(A[left], 2);
} else {
rightSquare = (int) Math.pow(A[right], 2);
}
}//end while
return res;
相关文章
- 求两个有序等长数组arr1,arr2,合成有序数组arr之后的上中位数是多少
- 将一个几乎有序的数组,排序好,几乎就是:要挪动i位置,最远不会挪动k个位置
- Java中用字节数组表示整数和用整数表示字节数组
- js对象键值对转换为数组包对象
- C++ 二维数组
- Android JNI编程(五)——C语言的静态内存分配、动态内存分配、动态创建数组
- 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
- LeetCode1095.之山脉数组中查找目标值(相关话题:多重二分)
- 【leetcode】26:删除有序数组中的重复项 II
- [LeetCode] 977. Squares of a Sorted Array 有序数组的平方值
- [LeetCode] Single Element in a Sorted Array 有序数组中的单独元素
- [LeetCode] 80. Remove Duplicates from Sorted Array II 有序数组中去除重复项之二
- [LeetCode] 88. Merge Sorted Array 混合插入有序数组
- leetcode 540. Single Element in a Sorted Array 有序数组中的单一元素