数组
88.合并两个有序数组
思路:i,j两个索引,谁大放谁,从后往前放。如果是谁小放谁从头开始放的话,需要重新开辟一个数组保存排序结果,再copy到nums1中,否则会有部分nums1元素提前就被覆盖掉。
细节:边界问题
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int i = m - 1, j = n - 1;
for(int k = m + n - 1; k >= 0; k--){
if(j < 0 || (i >= 0 && nums1[i] >= nums2[j])){
nums1[k] = nums1[i];
i--;
}else{
nums1[k] = nums2[j];
j--;
}
}
}
};
26.删除有序数组中的重复项(去重)
思路:遍历,与前面不一样的元素就可以单独拿出来,可以开辟一个新的容器装,也可以直接覆盖在原来的nums数组中,这样就省下了O(N)的开辟空间
细节:数组越界问题(考虑到有i-1)
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = 0;
for(int i = 0; i < nums.size(); i++){
if(i == 0 || nums[i] != nums[i - 1]){
nums[n] = nums[i];
n++;
}
}
return n;
}
};
283.移动零
思路:和上一题思路一样,看需要什么,上一题是需要和前一元素不同的元素,本题是需要不为0的元素。然后再在后面补0。
细节:忘记n++了
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int n = 0;
for(int i = 0; i < nums.size(); i++){
if(nums[i] != 0){
nums[n] = nums[i];
n++;
}
}
while(n < nums.size()){
nums[n] = 0;
n++;
}
}
};
704 二分查找
左闭右闭区间写法:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while(left <= right){
int middle = left + ((right-left)/2);
if(nums[middle]>target){
right = middle-1;
}else if(nums[middle]<target){
left = middle+1;
}else{
return middle;
}
}
return -1;
}
};
左闭右开区间写法:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while(left < right){
int middle = left + ((right-left)/2);
if(nums[middle]>target){
right = middle;
}else if(nums[middle]<target){
left = middle+1;
}else{
return middle;
}
}
return -1;
}
};
27.移除元素
其实就是要自己实现一个erase()
暴力解法:O(n^2)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
for(int i=0;i<size;i++){
if(nums[i]==val){
for(int j=i+1;j<size;j++){
nums[j-1] = nums[j];
}
i--;
size--;
}
}
return size;
}
};
双指针解法:O(n)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
for(int fastIndex=0;fastIndex<nums.size();fastIndex++){
if(nums[fastIndex]!=val){
nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
};
977.有序数组的平方
暴力法:先平方再排序,O(nlogn)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for(int i = 0; i < nums.size(); i++){
nums[i] *= nums[i];
}
sort(nums.begin(),nums.end());
return nums;
}
};
双指针法:O(n)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result(nums.size(), 0);
int k = nums.size() - 1;
for(int i = 0, j = nums.size() - 1; i <= j; ){
if(nums[i] * nums[i] < nums[j] * nums[j]){
result[k--] = nums[j] * nums[j];
j--;
}
else{
result[k--] = nums[i] * nums[i];
i++;
}
}
return result;
}
};
209.长度最小的子数组
暴力解法:O(n^2),两层for循环,可能会超时
注意:第二层循环找到了子串和>=target就可以break
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int sum = 0;
int subLength = 0;
for(int i = 0; i < nums.size(); i++){
sum = 0;
for(int j = i; j < nums.size(); j++){
sum += nums[j];
if(sum >= target){
subLength = j - i + 1;
result = result < subLength ? result : subLength;
break;
}
}
}
return result == INT32_MAX ? 0 : result;
}
};
滑动窗口:O(n),精髓之处是不断改变起始位置,找到满足条件的最小子串
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int sum = 0;
int subLength = 0;
int i = 0;//起始位置
for(int j = 0; j < nums.size(); j++){
sum += nums[j];
while(sum >= target){
subLength = (j - i + 1);
result = result < subLength ? result : subLength;
sum -= nums[i++];//不断变更子数组的起始位置
}
}
return result == INT32_MAX ? 0 : result;
}
};
59.螺旋矩阵②
一进循环深似海,从此offer是路人。边界处理问题,这里统一使用左闭右开的原则处理。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
//左闭右开原则
vector<vector<int>> res(n, vector<int>(n,0));
int loop = n / 2;//循环圈数
int startx = 0, starty = 0;//每一圈循环的起始位置
int count = 1;//存放的数
int i = 0, j = 0;//记录位置
int offset = 1;//用于控制边界
int mid = n / 2;//记录中间位置
while(loop--){
i = startx;
j = starty;
for(; j < n - offset; j++){
res[i][j] = count++;
}
for(; i < n - offset; i++){
res[i][j] = count++;
}
for(; j > starty; j--){
res[i][j] = count++;
}
for(; i > startx; i--){
res[i][j] = count++;
}
startx++;
starty++;
offset++;
}
if(n % 2 == 1){
res[mid][mid] = count;
}
return res;
}
};