数组理论基础
数组下标从0开始,数组在内存中连续存放
删除需要后面对前进行覆盖
二分查找
题目: 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
二分法使用前提:数组有序并且无重复元素
二分法的难点及核心:对于区间的管理,左闭右开还是左闭右闭
左闭右闭:left<=right 并且当middle > target 时候 right = middle-1
同理,左闭右开:left<right 并且当middle > target 时候 right = middle
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
#include<iostream>
#include<vector>
using namespace std;
class Solution {
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;
}
};
移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。例如给定 nums = [0,1,2,2,3,0,4,2], val = 2, 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
快速的方法是使用双指针法,通过一个for循环完成,快指针负责找到每个不等于val的元素并赋值给慢指针。慢指针指向新地址并向前移动,更新数组下标。
class Solution
{
public:
int removeElement(vector<int>& nums, int val)
{
int slow = 0;
for (int fast = 0; fast < nums.size(); fast++)
{
if (nums[fast] != val)
{
nums[slow++] = nums[fast];
}
}
return slow;
}
};
有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
核心点是数组是有序的,平方排序关键是取绝对值的最大数,所以对于有序数组一定是两头绝对值大,中间小的。故可以用双指针法,从两头比较得出较大的放在新数组里。
时间复杂度O(N);
#include<iostream>
using namespace std;
#include<vector>
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums)
{
int M = nums.size() - 1;
vector<int>result(nums.size(), 0);
for (int i = 0, j = nums.size() - 1; i <= j;)
{
if (nums[i] * nums[i] < nums[j] * nums[j])
{
result[M--] = nums[j] * nums[j];
j--;
}
else
{
result[M--] = nums[i] * nums[i];
i++;
}
}
return result;
}
};
长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
滑动窗口的入门解决方法。用J开始滑动并计算和sum+=nums[j]一旦发现超过target,则计算子串长度,并引入i 进行向前移动缩小窗口的滑动模式,然后通过巧妙地sum-=nums[i++]不断对符合要求的窗口进行i++的减小,直到在上一步的判断中,找到最小的result,注意最开始给result赋值一个最大的数,如果没有最小的符合要求则只取0的判断。
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int i=0;
int sum=0;
int subLenth =0;
for(int j=0;j<nums.size();j++)
{
sum+= nums[j];
while(sum>=target)
{
subLenth = (j-i+1);
result = result<subLenth?result :subLenth;
sum-=nums[i++];
}
}
return result == INT32_MAX ? 0 :result;
}
};
螺旋矩阵
给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
这题主要在用代码模拟过程,不涉及算法思路,主要涉及每一圈上下左右旋转时候,是否做到了闭开区间
#include<iostream>
using namespace std;
#include<vector>
class Solution {
public:
vector<vector<int>>gm(int n) {
vector<vector<int>>res(n, vector<int>(n, 0));
int startx = 0, starty = 0;
int loop = n / 2;
int mid = n / 2;
int count = 1;
int offset = 1;
int i, j;
while (loop--) {
i = startx;
j = starty;
for (j; j < n - offset; j++) {
res[i][j] = count++;
}
for (i; 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 += 1;
}
if (n % 2) {
res[mid][mid] = count;
}
return res;
}
};