完整代码:
#include <iostream>
#include <vector>
using namespace std;
//假设数组是[-5,1,2,3],平方后是[25,1,4,9],按“非递减顺序”排序后的整数数组为[1,4,9,25]。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
//定义一个result新数组,用于存储平方+排序后的结果。
vector<int> result(nums.size(),0); //【注意】这里一定一定要把result数组定义初始化!否则会越界访问、编译报错。
//定义一个索引指针,指向新数组的最后一个位置。先出来的平方数最大,所以放到新数组最后一个位置,这样新数组才是由小到大顺序。
int k = nums.size() - 1;
for (int i = 0, j = nums.size() - 1; i <= j;) { //【注意】i++和j--要写到for()括号外面才对!
if (nums[i]* nums[i] > nums[j]*nums[j]) {
result[k] = nums[i] * nums[i];
//result向量在初始化时是空的,没有足够的空间来存储元素。因此,直接访问result[k]会导致越界访问,引发未定义的行为。
//result.push_back(nums[i] * nums[i]); //push_back 函数就实现了把nums[i] * nums[i]的值放在result新数组的末尾。
i++;
k--; //也可以简写成result[k] = nums[i] * nums[i];
}
else {
result[k] = nums[j] * nums[j];
//result.push_back(nums[j] * nums[j]);
j--;
k--;
}
}
//reverse(result.begin(), result.end()); // 反转结果,使其按非递减顺序排列
return result;
}
};
int main() {
vector<int> nums = { -5,1,2,3 };
// 创建Solution类的实例
Solution solution;
// 调用sortedSquares方法,传入nums
vector<int> squaredSorted = solution.sortedSquares(nums);
for (int i = 0; i <= squaredSorted.size() - 1; ++i) {
cout << squaredSorted[i]<<" ";
}
cout << endl;
return 0;
}
运行结果如下图:
· 需要注意的点:
1.
vector<int> result(nums.size(), 0);
什么意思?
在 C++ 的 <vector>
库中,这行代码:
vector<int> result(nums.size(), 0);
意味着创建了一个类型为 vector<int>
的新动态数组 result
,它的大小由 nums.size()
确定,即与另一个数组 nums
的大小相同。第二个参数 0
表示数组中每个元素的初始值都将被设置为 0
。
具体来说:
vector<int>
:声明了一个整数类型的动态数组。nums.size()
:调用了另一个数组nums
的size()
成员函数,这个函数返回nums
数组中的元素数量。0
:数组result
中的每个位置都被初始化为0
。
这种初始化方式常用于需要一个固定大小且默认值的数组时。在排序问题中,这可以确保 result
数组有足够的空间来存储所有计算出的平方值,并且避免了使用 push_back
时可能发生的多次内存分配,这可以提高代码的效率。
第二种方法是用push_back:【把图中第11行for循环括号里的i++和j--删掉应该就可以了】
在我原来的代码中,错误出现在以下两行:
result[k] = nums[i] * nums[i];
result[k] = nums[j] * nums[j];
这两行尝试通过索引k
来访问result
向量并赋值。然而,这里存在两个问题:
①result
向量在初始化时是空的,没有足够的空间来存储元素。因此,直接访问result[k]
会导致越界访问,引发未定义的行为。
错误写法是:
vector<int> result;
正确写法是:
vector<int> result(nums.size(),0);
②即使你在代码开始之前使用result.resize(nums.size())
调整了result
向量的大小,问题仍然存在。因为你在循环中使用了i++
和j--
的操作,这意味着你实际上是跳过了某些索引位置,而没有按正确的顺序访问和赋值。
要解决这个问题,可以使用result.push_back()
函数将平方值添加到result
向量的末尾,而不是直接访问索引。
push_back()函数的用法:
push_back() 在Vector最后添加一个元素(参数为要插入的值)
-
//在vec尾部添加10
-
vector<int> vec;
-
vec.push_back(10);
-
类似的:
pop_back() //移除最后一个元素
clear() //清空所有元素
empty() //判断vector是否为空,如果返回true为空
2.
for (int i = 0, j = nums.size() - 1; i <= j;i++,j--)
{
......
}
for (int i = 0, j = nums.size() - 1; i <= j;)
{
......
}
Q:为什么第一种写法错误,第二种写法正确?
A:因为i++和j--是有条件的,取决于nums[i]和nums[j]元素的平方谁更大,大的那个平方值放到新数组result中,同时变量++或者--;平方值小的对应的i或j是不变化的。我第一遍做错就是错在这一步了,所以这里需要特别注意一下!