给你一个按 非递减顺序 排序的整数数组 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]来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/squares-of-a-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
最简单的一个思路:先平方,后排序。
看了题解之后,又发现了一位大佬提出的新思路,是通过双指针实现的 ,具体就是,因为原数组是按照顺序排列的元素且有正负值,所以平方最大值一定是在头部或者尾部。因此,在数组头尾分别定义一个指针,判断两个指针指向元素平方的大小,同时定义一个与原数组大小相同的新数组,把较大的那一个平方值存入新数组的尾部,再进行指针移动,比较,存入新数组,直到新数组存入完成。于是,我也尝试复现了一下。
int* sortedSquares(int* nums, int numsSize, int* returnSize){
//返回的数组大小就是原数组大小
*returnSize = numsSize;
//创建两个指针,right指向数组最后一位元素,left指向数组第一位元素
int right = numsSize - 1;
int left = 0;
//最后要返回的结果数组
//这里要注意,c语言给指针变量分配一个整型存储空间的方法
int* ans = (int*)malloc(sizeof(int) * numsSize);
int index;
for(index = numsSize - 1; index >= 0; index--) {
//左指针指向元素的平方
int lSquare = nums[left] * nums[left];
//右指针指向元素的平方
int rSquare = nums[right] * nums[right];
//若左指针指向元素平方比右指针指向元素平方大,将左指针指向元素平方放入结果数组。左指针右移一位
if(lSquare > rSquare) {
ans[index] = lSquare;
left++;
}
//若右指针指向元素平方比左指针指向元素平方大,将右指针指向元素平方放入结果数组。右指针左移一位
else {
ans[index] = rSquare;
right--;
}
}
//返回结果数组
return ans;
}
虽然通过了,但是我感觉对于C语言的指针不熟悉,毕竟上一次用C语言写算法,还是2019年,所以我又去学了一下指针。
我的疑问:我看了一些解析,说p是指针,*p是p指向的内容,那为啥上面的代码里, ans[index] = lSquare;会是一个数值呢?不应该是*ISquare吗?
答疑解惑:
我先来c语言中文网仔细复习了一遍指针。C语言指针详解,30分钟玩转C语言指针 (biancheng.net)http://c.biancheng.net/c/80/
如果一个变量存储了一份数据的指针,我们就称它为指针变量。指针变量的值就是某份数据的地址,定义时,int *name = value;*表示这是一个指针变量,int表示该指针变量所指向的数据的类型 。定义指针变量时必须带*,给指针变量赋值时不能带*。
第一行代码是将a的地址复制给了指针变量p,第二行代码是可以通过*p来实现获取a的值(*&a等价于a,即*p就是a中的内容)
关于 * 和 & 的谜题假设有一个 int 类型的变量 a,pa 是指向它的指针,那么*&a和&*pa分别是什么意思呢?
*&a可以理解为*(&a),&a表示取变量 a 的地址(等价于 pa),*(&a)表示取这个地址上的数据(等价于 *pa),绕来绕去,又回到了原点,*&a仍然等价于 a。
&*pa可以理解为&(*pa),*pa表示取得 pa 指向的数据(等价于 a),&(*pa)表示数据的地址(等价于 &a),所以&*pa等价于 pa。
基础搞完了,和本题最相关的数组指针来了。
在数组中,数组名可以认为是一个指针,它指向数组的第 0 个元素。在C语言中,我们将第 0 个元素的地址称为数组的首地址。
我看了大概20分钟,感觉没有用,它讲的我都懂,但是对于上面那一块代码的理解,毫无帮助。
然后······惊喜来了,我按照我的理解,按照指针的赋值把代码修改了一遍,改成下面的样子。
int* sortedSquares(int* nums, int numsSize, int* returnSize){
//返回的数组大小就是原数组大小
*returnSize = numsSize;
//创建两个指针,right指向数组最后一位元素,left指向数组第一位元素
int right = numsSize - 1;
int left = 0;
//最后要返回的结果数组
//这里要注意,c语言给指针变量分配一个整型存储空间的方法
int* ans = (int*)malloc(sizeof(int) * numsSize);
int index;
for(index = numsSize - 1; index >= 0; index--) {
//左指针指向元素的平方
int a = nums[left]*nums[left];
int *lSquare = &a;
//右指针指向元素的平方
int b = nums[right]*nums[right];
int *rSquare = &b;
//若左指针指向元素平方比右指针指向元素平方大,将左指针指向元素平方放入结果数组。左指针右移一位
if(*lSquare > *rSquare) {
ans[index] = *lSquare;
left++;
}
//若右指针指向元素平方比左指针指向元素平方大,将右指针指向元素平方放入结果数组。右指针左移一位
else {
ans[index] = *rSquare;
right--;
}
}
//返回结果数组
return ans;
}
完全按照
定义指针时,使用*,给指针赋值时,使用&号
于是,代码通过了!感觉做题太少了,可能我还没有掌握简写方法吧。
但是这样按照*和&方式来写代码,真的清楚多了。
yeah!



