算法----数组

二分查找(leetcode.704)

情况一:给定区间为左闭右闭 [left,right]

初始left值为0,right值为numsize-1

循环条件 left <= right

更新右边界 mid-1 左边界 mid+1

ini 复制代码
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        while(left <= right){
            int mid = (right - left) / 2 + left;
            int num = nums[mid];
            if (num == target) {
                return mid;
            } else if (num > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }
};

情况二:给定区间为左闭右开 [left,right)

初始left值为0,right值为numsize

循环条件 left < right

更新右边界 mid 左边界 mid+1

ini 复制代码
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0, right = nums.size();
        while(left < right){
            int mid = (right - left) / 2 + left;
            int num = nums[mid];
            if (num == target) {
                return mid;
            } else if (num > target) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }
};

数组移除指定元素(leetcode.27)

解法一:双指针

sql 复制代码
class Solution { 
    public int removeElement(int[] nums, int val) { 
        int n = nums.length; 
        int left = 0; 
        for(int right = 0; right < n; right++){//如果不需要删除,什么都不用做,right继续移动就好 
            if(nums[right] != val){//不需要删除,直接移到下标为left处 
            nums[left] = nums[right]; left++;
            }
        } 
        return left; 
    } 
}

解法二:双指针优化

题目只要求返回最终的数组大小,数组内的元素顺序可以任意

sql 复制代码
class Solution { 
    public int removeElement(int[] nums, int val) { 
        int left = 0; 
        int right = nums.length; 
        while(left < right){ 
            if(nums[left] == val){//由于顺序不影响结果,可以直接把右端元素取代左端元素,通过循环实现不断取代 
                nums[left] = nums[right-1]; 
                right--; 
            }else{ 
                left++;//如果不需要删除,left移动即可 
            } 
        } 
        return left; 
    } 
}

有序数组的平方(leetcode.977)

双指针

原数组从小到大排列且有负数,那么平方后最大值只能在两个边界取到,因此思路是从边界向中间靠拢,逐步走出大值并从动态数组末尾依次往前添加

ini 复制代码
class Solution { 
    public: vector<int> sortedSquares(vector<int>& nums) { 
        int n = nums.size(); 
        vector<int> ans(n); 
        for (int i = 0, j = n - 1, pos = n - 1; i <= j;) { 
            if (nums[i] * nums[i] > nums[j] * nums[j]) { 
                ans[pos] = nums[i] * nums[i]; ++i; 
            } else { 
                ans[pos] = nums[j] * nums[j]; --j; 
            } 
            --pos; 
        } 
    return ans; 
    } 
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组 nums 的长度。
  • 空间复杂度:O(1)。除了存储答案的数组以外,我们只需要维护常量空间。

推荐另一种形式

ini 复制代码
class Solution { 
    public: vector<int> sortedSquares(vector<int>& nums) { 
        int n = nums.size() - 1; 
        vector<int> ans(n); 
        for (int i = 0, j = nums.size()-1 ; i <= j;) { 
            if (nums[i] * nums[i] > nums[j] * nums[j]) { 
                ans[n] = nums[i] * nums[i]; ++i; 
            } else { 
                ans[n] = nums[j] * nums[j]; --j; 
            } 
            --n; 
        } 
    return ans; 
    } 
}

长度最小的子数组(leetcode.209)

滑动窗口

关键点:

  • 子数组元素要连续
  • 当满足sum>=target时,不能停止(即不能使用if),因为如1,1,1,1,1,100的情况,如果target为100,则只有end到100时才第一次满足sum>=target,但这实际上不是最短的子数组,辅以start往后移动以确保得到最短的子数组
ini 复制代码
class Solution {
public:
    int minSubArrayLen(int target, vector<int>& nums) {
        int n = nums.size();
        if(n == 0){
            return 0;
        }
        int ans = INT_MAX;
        int start = 0, end = 0;
        int sum = 0;
        for(end = 0; end < n; end++){
            sum += nums[end];
            while(sum >= target){
                ans = min(ans, end - start + 1);
                sum -= nums[start];
                start++;
            }
        }
        return ans == INT_MAX ? 0 : ans;
    }
};

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组的长度。指针 start 和 end 最多各移动 n 次。
  • 空间复杂度:O(1)。
相关推荐
逆境不可逃6 分钟前
LeetCode 热题 100 之 230. 二叉搜索树中第 K 小的元素 199. 二叉树的右视图 114. 二叉树展开为链表
算法·leetcode·职场和发展
一个有温度的技术博主10 分钟前
Redis Cluster 核心原理:哈希槽与数据路由实战
redis·算法·缓存·哈希算法
wfbcg21 分钟前
每日算法练习:LeetCode 15. 三数之和 ✅
算法·leetcode·职场和发展
2301_8227032027 分钟前
开源鸿蒙跨平台Flutter开发:跨端图形渲染引擎的类型边界与命名空间陷阱:以多维雷达图绘制中的 dart:ui 及 StrokeJoin 异常为例
算法·flutter·ui·开源·图形渲染·harmonyos·鸿蒙
y = xⁿ29 分钟前
【LeetCode Hot100】双指针:分离指针
算法·leetcode
学习永无止境@30 分钟前
Verilog中有符号数计算
图像处理·算法·fpga开发
小肝一下1 小时前
每日两道力扣,day6
数据结构·c++·算法·leetcode·双指针·hot100
ambition202421 小时前
【算法详解】飞机降落问题:DFS剪枝解决调度问题
c语言·数据结构·c++·算法·深度优先·图搜索算法
徒 花1 小时前
Python知识学习08
java·python·算法
chushiyunen1 小时前
milvus笔记、常用表结构
笔记·算法·milvus