数组【二分,双指针,滑动窗口,模拟】

刷题目录

数组的理论知识

二维数组不是连续地址空间,而是一个线性数组存放着 其它数组的首地址
在这里插入图片描述

35. 搜索插入位置(二分)

以后大家「只要看到面试题里给出的数组是有序数组,都可以想一想是否可以使用二分法。」
二分出来的一定是符合边界的,但不一定符合题意!要特判!
这一题解法1:二分边界是 >= target的值, 解法2:考虑 二分边界是 <= target的值
时间复杂度:O(logn)

解法1:二分边界是 >= target的值

class Solution {
    
    
public:
    int searchInsert(vector<int>& nums, int target) {
    
    
        // 已排好序,二分查找
        int l = 0,r = nums.size() ; // 预留多一个位置,防止插在最后
        while(l < r)
        {
    
    
            int mid = l + r >> 1;
            if(nums[mid] >= target) r = mid;
            else l = mid + 1;
        }

        return r;
    }
};

解法2:二分边界是 <= target的值

class Solution {
    
    
public:
    int searchInsert(vector<int>& nums, int target) {
    
    
        int l = 0, r = nums.size() - 1;
        while(l < r)
        {
    
    
            int mid = l + r + 1>> 1;
            if(nums[mid] <= target) l = mid;
            else r = mid - 1;
        }

        if(target <= nums[0]) return 0; // 特判
        if(nums[r] != target) return r + 1;
        return r;
    }
};

27. 移除元素(双指针)

双指针,可从O(n ^ 2)降到O(n)
class Solution {
    
    
public:
    int removeElement(vector<int>& nums, int val) {
    
    
        // 快慢指针
        // 时间复杂度:O(n)
        // 空间复杂度:O(1)
        int slow = 0;
        for(int fast = 0;fast < nums.size(); fast ++)
        {
    
    
            if(val != nums[fast]) nums[slow ++ ] = nums[fast];
        }

        return slow;
    }
};

209. 长度最小的子数组(滑动窗口)

滑动窗口:利用单调性优化,可从O(n ^ 2) 降到 O(n)
注意边界:没有符合条件的子数组
class Solution {
    
    
public:
    int minSubArrayLen(int s, vector<int>& nums) {
    
    
     	// 时间复杂度O(n)
        int len = nums.size() + 1;
        int sum = 0;
        for(int i = 0, j = 0;i < nums.size();i ++ )
        {
    
    
            sum += nums[i];
            while(sum >= s)
            {
    
    
                len = min(len, i - j + 1); // 长度是i - j + 1;
                sum -= nums[j ++ ];
            }
            
        }

        if(len == nums.size() + 1) return 0; // 特判,表示没有符合条件的连续子数组
        return len;
    }
};

59. 螺旋矩阵 II(模拟)

定义四个偏移量,利用方向矢量来模拟
class Solution {
    
    
public:
    vector<vector<int>> generateMatrix(int n) {
    
    
        vector<vector<int>> res(n,vector<int>(n)); // 初始化
        vector<vector<bool>> st(n,vector<bool>(n,false)); // 是否访问过

        int dx[4] = {
    
    -1,0,1,0}, dy[4] = {
    
    0,1,0,-1}; // 上右下左
        int x = 0,y = 0; // 初始坐标
        int d = 1; // 初始方位
        for(int i = 1;i <= n * n ;i ++ )
        {
    
    
            res[x][y] = i;
            st[x][y] =  true;
            int tx = x + dx[d], ty = y + dy[d];
            if(tx < 0 || tx >= n || ty < 0 || ty >= n || st[tx][ty]) // 出界或者已访问,就转向
            {
    
    
                d = (d + 1) % 4;
                tx = x + dx[d], ty = y + dy[d]; // 转向,重新计算坐标
            } 
            x = tx, y = ty;
        }

        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43154149/article/details/112129550