题目链接:
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
文字讲解:代码随想录
代码:超出了时间限制
class Solution {
public:
vector sortedSquares(vector& nums) {
int length = nums.size();
for(int i = 0; i < length; i++){
nums[i] = pow(nums[i], 2);
}
//冒泡排序
for(int i = 0; i < length - 1; i++){
for(int j = 0; j < length - i - 1; j++){
if(nums[j] > nums[j + 1]){
int temp = nums[j + 1];
nums[j + 1] = nums[j];
nums[j] = temp;
}
}
}
return nums;
}
};
代码:
class Solution {
public:
vector sortedSquares(vector& nums) {
for(int i = 0; i < nums.size(); i++){
nums[i] = pow(nums[i], 2);
}
sort(nums.begin(), nums.end());
return nums;
}
};
思路:用了现成的函数sort()
代码:(mine)
class Solution {
public:
vector sortedSquares(vector& nums) {
int k = nums.size() - 1;
vector result(nums.size(), 0);
for(int leftIndex = 0, rightIndex = nums.size() - 1; leftIndex <= rightIndex;){
if(abs(nums[leftIndex]) > abs(nums[rightIndex])){
result[k--] = nums[leftIndex] * nums[leftIndex];
leftIndex++;
}
else{
result[k--] = nums[rightIndex] * nums[rightIndex];
rightIndex--;
}
}
return result;
}
};
思路:数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间,此时可以考虑双指针法;建立一个新数组,把求平方后的元素逐个按顺序填入,然后返回新数组
左指针:一开始指向最左侧
右指针:一开始指向最右侧
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
文字讲解:代码随想录
思路:叠加两个for循环
代码:运行超时,程序的话我感觉没什么问题
class Solution {
public:
int minSubArrayLen(int target, vector& nums) {
int min = nums.size() + 1;
for(int i = 0; i <= nums.size() - 1; i++){
int sum = 0;
for(int j = i; j <= nums.size() - 1; j++){
sum += nums[j];
if(sum >= target){
int temp = j - i + 1;
min = (temp < min ? temp : min);
break;
}
}
}
return (min == nums.size() + 1 ? 0 : min);
}
};
思路:叠加两个for循环
代码:代码随想录给出的代码也运行超时,我的方法和这个给出的暴力解法思路基本一致,没什么区别
class Solution {
public:
int minSubArrayLen(int s, vector& nums) {
int result = INT32_MAX; // 最终的结果
int sum = 0; // 子序列的数值之和
int subLength = 0; // 子序列的长度
for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
sum = 0;
for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
sum += nums[j];
if (sum >= s) { // 一旦发现子序列和超过了s,更新result
subLength = j - i + 1; // 取子序列的长度
result = result < subLength ? result : subLength;
break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
}
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}
};
思路1:利用【一个for循环 + 一个while循环】即可实现,其实从动画中可以发现滑动窗口也可以理解为双指针法的一种,只不过这种解法更像是一个窗口的移动,所以叫做滑动窗口更适合一些
思路2:while里面的语句是精髓
注:所以要写对这道题,一定要注意下一个可能的子数组的起点会是哪里这个目标,从而在while循环中重新制定子数组的起点位置(即左指针的位置)
代码:
class Solution {
public:
int minSubArrayLen(int target, vector& nums) {
int sum = 0; //滑动窗口 数字之和
int leftIndex = 0; //滑动窗口 起始位置
int min = nums.size() + 1; //滑动窗口 长度
for(int rightIndex = 0; rightIndex <= nums.size() - 1; rightIndex++){
sum += nums[rightIndex];
while(sum >= target){
min = (min > rightIndex - leftIndex + 1 ? rightIndex - leftIndex + 1 : min);
sum -= nums[leftIndex];
leftIndex++;
}
}
return (min == nums.size() + 1 ? 0 : min);
}
};
解析:上述两种方法的代码中,都是两个循环的嵌套,那为什么时间复杂度不一样
注:来自代码随想录的讲解
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
文字讲解:代码随想录
视频讲解:一入循环深似海 | LeetCode:59.螺旋矩阵II_哔哩哔哩_bilibili
思路:一定要注意【循环】【不变量】原则
注:如果不懂可以看看讲解视频,讲的很清楚
代码:
class Solution {
public:
vector> generateMatrix(int n) {
vector> res(n, vector(n, 0)); //使用vector定义一个二维数组
int loop = n / 2; //总共转几圈
int startx = 0; //每一圈起始位置的行index
int starty = 0; //每一圈起始位置的列index
int offset = 1; //用来辅助确定终止位置index
int count = 1; //待填入数字
int i; //i 代表行
int j; //j 代表列
while(loop){
for(j = starty; j < n - offset; j++){
res[startx][j] = count;
count++;
}
for(i = startx; i < n - offset; i++){
res[i][j] = count;
count++;
}
for(; j > starty; j--){
res[i][j] = count;
count++;
}
for(; i > startx; i--){
res[i][starty] = count;
count++;
}
// 下一圈开始的时候,需要更新新的一圈的起始位置
startx++;
starty++;
//更新终止位置的辅助值
offset++;
loop--;
}
if(n % 2 == 1){
res[startx][starty] = count;
}
return res;
}
};