Given an integer array nums sorted in non-decreasing order, return an array of the squares of each number sorted in non-decreasing order .
Example 1:
Example 2:
Constraints:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums is sorted in non-decreasing order.
Follow up: Squaring each element and sorting the new array is very trivial, could you find an O(n) solution using a different approach?
解题思路:
题意理解:
一个数组从小到大排列,有负数,需要对整个数组平方之后在从小到大排序输出;
双指针:
平方后,最大元素在两头,而不是中间
对于结果的数组,从后往前赋值,两个指针分别指向平方后的数组前后,先把较大的放进结果数组;
需要注意的要点:
要靠了最后两个指针碰头的情况。
// O(n)我自己的实现
class Solution {
public:
vector sortedSquares(vector& nums) {
vector res(nums.size(), 0);
int left = 0, right = nums.size() - 1;
int index = right;
while(right > left) {
int LValue = pow(nums[left], 2);
int RValue = pow(nums[right], 2);
if (LValue > RValue) {
res[index--] = LValue;
left ++;
}
else if (LValue < RValue) {
res[index--] = RValue;
right --;
}
else {
res[index--] = RValue;
right --;
}
}
res[index] = pow(nums[left], 2);
return res;
}
};
// carl的实现
class Solution {
public:
vector sortedSquares(vector& A) {
int k = A.size() - 1;
vector result(A.size(), 0);
for (int i = 0, j = A.size() - 1; i <= j;) { // 注意这里要i <= j,因为最后要处理两个元素
if (A[i] * A[i] < A[j] * A[j]) {
result[k--] = A[j] * A[j];
j--;
}
else {
result[k--] = A[i] * A[i];
i++;
}
}
return result;
}
};
Given an array of positive integers nums and a positive integer target, return *the minimal length of a *
subarray
whose sum is greater than or equal to* target. If there is no such subarray, return 0 instead.
Example 1:
Example 2:
Example 3:
Constraints:
1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 104
Follow up: If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log(n)).
解题思路:
利用曾经学习过的双指针:
right指针
不断往前走,直到区间内的数组和达到要求
left指针
当区间内的元素满足要求时,向前走,缩小数组长度,直到不满足条件
需要注意的要点:
注意对于每个元素是先加上去,然后在做判断是否要更新left指针
// 我的实现O()
class Solution {
public:
int minSubArrayLen(int target, vector& nums) {
int sum = 0;
int left = 0;
int right = 0;
int minLength = 10e6;
for(right; right < nums.size(); ++ right) {
sum += nums[right];
if (sum >= target) { //这个判断其实没必要
while(sum >= target) {
sum -= nums[left];
left ++;
}
# left-1是因为经过上一个while,目前的子序列已不满足条件
minLength = (right - (left-1)) + 1 < minLength ? (right - (left-1)) + 1 : minLength;
}
}
minLength = minLength == 10e6 ? 0 : minLength;
return minLength;
}
};
// carl实现
class Solution {
public:
int minSubArrayLen(int s, vector& nums) {
int result = INT32_MAX;
int sum = 0; // 滑动窗口数值之和
int i = 0; // 滑动窗口起始位置
int subLength = 0; // 滑动窗口的长度
for (int j = 0; j < nums.size(); j++) {
sum += nums[j];
// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
while (sum >= s) {
subLength = (j - i + 1); // 取子序列的长度
result = result < subLength ? result : subLength;
sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}
};
Given a positive integer n, generate an n x nmatrix filled with elements from 1 to n2 in spiral order.
Example 1:
Example 2:
Constraints:
1 <= n <= 20
解题思路:
在外面一圈一圈的处理
对于奇数的边长,单独处理中心
每条边的左右边界应当一致,方便代码理解
需要注意的要点:
耐心一些
//自己的实现
class Solution {
public:
vector> generateMatrix(int n) {
vector> table(n, vector(n, 0));;
int length = n; // 这一圈的方框的size
int tmp_n = n; // n的备份,是要变的
int row_start = 0; // 这个方框的左上角的x坐标
int col_start = 0; // 这个方框的左上角的y坐标
int elem_start = 0; // 这个方框的起始元素,由于index从1开始,因此,这里实际上是上一圈的结束元素
int elem_size = pow(tmp_n, 2) - pow(tmp_n - 2, 2); //这一圈有多少个元素
while(length > 1) {
for(int i = 1; i <= elem_size; ++ i) {
if(i <= length) { //一圈的上面
table[row_start][col_start+i-1] = elem_start + i;
}
else if(i > length && i <= 2*length - 1) { //一圈的右边
table[row_start+(i-length)][col_start+length-1] = elem_start + i;
}
else if(i > 2*length - 1 && i <= 3*(length-1)+1) { //一圈的下边
table[row_start+length-1][col_start+length-1-(i-(2*length - 1))] = elem_start + i;
}
else if(i > 3*(length-1)+1 && i <= elem_size) { //一圈的左边
table[row_start+length-1-(i-(3*(length-1)+1))][col_start] = elem_start + i;
}
}
// 绕完一圈,更新参数
col_start += 1; //起始坐标向右下移动一个
row_start += 1; //起始坐标向右下移动一个
elem_start += elem_size; //起始元素加上这一圈走过的元素
tmp_n -= 2; //圈的大小减小
elem_size = pow(tmp_n, 2) - pow(tmp_n-2, 2); //元素数目重新计算
length -= 2; //圈的边长减小
}
//若起始边长是奇数,填充中心
if(n % 2 != 0) {
table[n/2][n/2] = pow(n, 2);
}
// for(int i = 0; i < n; ++ i) {
// for(int j = 0; j < n; ++ j) {
// cout << table[i][j] << " ";
// }
// cout << endl;
// }
return table;
}
};
// carl 实现
public:
vector> generateMatrix(int n) {
vector> table(n, vector(n, 0));;
int loop = n / 2;
int mid = loop;
int startx=0, starty=0;
int offset=1;
int count = 1;
int length = n;
int i, j;
while(loop --) {
i = startx;
j = starty;
for(; j < starty + length - offset; ++ j) {
table[i][j] = count ++;
}
for(; i < startx + length - offset; ++ i) {
table[i][j] = count ++;
}
for(; j > starty; -- j) {
table[i][j] = count ++;
}
for(; i > startx; -- i) {
table[i][j] = count ++;
}
startx ++;
starty ++;
length -= 2;
}
if (n % 2) {
table[mid][mid] = count;
}
return table;
}
双指针思想
快慢指针
前后指针
区间不变量的控制
文章中LeetCode的题目来自LeetCode官网:https://leetcode.cn/problems