算法学习-基础算法

基础算法

一.二分查找

1.模版

boolean check(int x) {
}

int search(int left, int right) {
    while (left < right) {
        int mid = (left + right) >> 1;
        if (check(mid)) {
            //满足条件,向寻找范围继续寻找,例如我要找更靠左的:r = m 
            right = mid;
        } else {
            left = mid + 1;
        }
    }
    return left;
}




boolean check(int x) {
}

int search(int left, int right) {
    while (left < right) {
        int mid = (left + right + 1) >> 1;
        if (check(mid)) {
            left = mid;
        } else {
            right = mid - 1;
        }
    }
    return left;
}

在这里插入图片描述

2.使用场景

2.1.普通二分查找
2.2.最小化最大值(本质是二分求最小值)
2.3.最大化最小值(本质是二分求最大值)

二.前缀和与差分数组

1.一维前缀和

class NumArray {
    // 前缀和数组
    private int[] preSum;

    /* 输入一个数组,构造前缀和 */
    public NumArray(int[] nums) {
        // preSum[0] = 0,便于计算累加和
        preSum = new int[nums.length + 1];
        // 计算 nums 的累加和
        for (int i = 1; i < preSum.length; i++) {
            preSum[i] = preSum[i - 1] + nums[i - 1];
        }
    }
    
    /* 查询闭区间 [left, right] 的累加和 */
    public int sumRange(int left, int right) {
        return preSum[right + 1] - preSum[left];
    }
}

2.二维前缀和

class NumMatrix {
    int[][] preSum ;
    public NumMatrix(int[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;
        preSum = new int[m+1][n+1];
        for(int i = 0;i<m;i++){
            for(int j = 0;j<n;j++){
                preSum[i+1][j+1] = preSum[i+1][j] + preSum[i][j+1] - preSum[i][j] + matrix[i][j];
            }
        }
    }

    public int sumRegion(int row1, int col1, int row2, int col2) {
        return preSum[row2+1][col2+1] - preSum[row2+1][col1] - preSum[row1][col2+1] + preSum[row1][col1];
    }
}

/**
 * Your NumMatrix object will be instantiated and called as such:
 * NumMatrix obj = new NumMatrix(matrix);
 * int param_1 = obj.sumRegion(row1,col1,row2,col2);
 */

LeetCode例题

3.哈希+前缀和(子数组统计计数)

类似两数之和思路,要学会等式转换,注意设置map的下标,是否加1
LeetCode例题前缀异或和

4.一维差分数组

差分数组的主要适用场景是频繁对原始数组的某个区间的元素进行增减。
在这里插入图片描述

public class Solution {
    public void modifyArray(int[] nums, int k) {
        int n = nums.length;
        int[] d = new int[n + 1]; // 差分数组
        int sumD = 0; // 累积差分值
        
        for (int i = 0; i < n; i++) {
            sumD += d[i];
            // 更新nums[i]的逻辑,根据具体问题调整
            nums[i] += sumD;
            
            // 根据条件更新差分数组
            if (需要更新条件) {
                int change = 计算需要的变化值;
                sumD -= change; // 应用变化到sumD
                d[i] += change; // 当前位置开始应用变化
                if (i + k < n) {
                    d[i + k] -= change; // 在i+k处抵消前面的变化
                }
            }
        }
        
        // 可以在这里添加逻辑,根据需要处理nums数组
    }
}

LeetCode例题

5.二维差分数组

class Solution {
    public int[][] rangeAddQueries(int n, int[][] queries) {
        // 二维差分模板
        //往nn矩阵左上加一行一列,主要是为了前缀和舒服,
        //往nn矩阵右下加一行一列,主要是为了操作差分数组方便。
        int[][] diff = new int[n + 2][n + 2], ans = new int[n][n];
        for (int[] q : queries) {
            int r1 = q[0], c1 = q[1], r2 = q[2], c2 = q[3];
            ++diff[r1 + 1][c1 + 1];
            --diff[r1 + 1][c2 + 2];
            --diff[r2 + 2][c1 + 1];
            ++diff[r2 + 2][c2 + 2];
        }
        // 用二维前缀和复原
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                ans[i - 1][j - 1] = diff[i][j] += diff[i][j - 1] + diff[i - 1][j] - diff[i - 1][j - 1];
        return ans;
    }
}

LeetCode例题

  • 17
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱敲代码的林先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值