刷题笔记 框架

二叉树遍历 https://labuladong.gitee.io/algo/di-ling-zh-bfe1b/dong-ge-da-334dd/

void traverse(TreeNode* root) {
    
    
    if (root == nullptr) {
    
    
        return;
    }
    // 前序位置
    traverse(root->left);
    // 中序位置
    traverse(root->right);
    // 后序位置
}

动态规划 https://labuladong.gitee.io/algo/di-ling-zh-bfe1b/dong-tai-g-1e688/

# 自顶向下递归的动态规划
def dp(状态1, 状态2, ...):
    for 选择 in 所有可能的选择:
        # 此时的状态已经因为做了选择而改变
        result = 求最值(result, dp(状态1, 状态2, ...))
    return result

# 自底向上迭代的动态规划
# 初始化 base case
dp[0][0][...] = base case
# 进行状态转移
for 状态1 in 状态1的所有取值:
    for 状态2 in 状态2的所有取值:
        for ...
            dp[状态1][状态2][...] = 求最值(选择1,选择2...)

回溯算法 https://labuladong.gitee.io/algo/di-ling-zh-bfe1b/hui-su-sua-c26da/

result = []
def backtrack(路径, 选择列表):
    if 满足结束条件:
        result.add(路径)
        return
    
    for 选择 in 选择列表:
        做选择
        backtrack(路径, 选择列表)
        撤销选择

BFS 层序遍历 https://labuladong.gitee.io/algo/di-ling-zh-bfe1b/bfs-suan-f-463fd/

int BFS(Node start, Node target) {
    
    
    queue<Node> q; // 核心数据结构
    unordered_set<Node> visited; // 避免走回头路
    
    q.push(start); // 将起点加入队列
    visited.insert(start);
    int step = 0; // 记录扩散的步数

    while (!q.empty()) {
    
    
        int sz = q.size();
        /* 将当前队列中的所有节点向四周扩散 */
        for (int i = 0; i < sz; i++) {
    
    
            Node cur = q.front();
            q.pop();
            /* 划重点:这里判断是否到达终点 */
            if (cur == target)
                return step;
            /* 将 cur 的相邻节点加入队列 */
            for (Node x : cur.adj()) {
    
    
                if (visited.count(x) == 0) {
    
    
                    q.push(x);
                    visited.insert(x);
                }
            }
        }
        /* 划重点:更新步数在这里 */
        step++;
    }
}

二分查找 https://labuladong.gitee.io/algo/di-ling-zh-bfe1b/wo-xie-le–3c789/

int binary_search(vector<int>& nums, int target) {
    
    
    int left = 0, right = nums.size() - 1; 
    while(left <= right) {
    
    
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
    
    
            left = mid + 1;
        } else if (nums[mid] > target) {
    
    
            right = mid - 1; 
        } else if(nums[mid] == target) {
    
    
            // 直接返回
            return mid;
        }
    }
    // 直接返回
    return -1;
}

int left_bound(vector<int>& nums, int target) {
    
    
    int left = 0, right = nums.size() - 1;
    while (left <= right) {
    
    
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
    
    
            left = mid + 1;
        } else if (nums[mid] > target) {
    
    
            right = mid - 1;
        } else if (nums[mid] == target) {
    
    
            // 别返回,锁定左侧边界
            right = mid - 1;
        }
    }
    // 判断 target 是否存在于 nums 中
    // 此时 target 比所有数都大,返回 -1
    if (left == nums.size()) return -1;
    // 判断一下 nums[left] 是不是 target
    return nums[left] == target ? left : -1;
}

int right_bound(vector<int>& nums, int target) {
    
    
    int left = 0, right = nums.size() - 1;
    while (left <= right) {
    
    
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
    
    
            left = mid + 1;
        } else if (nums[mid] > target) {
    
    
            right = mid - 1;
        } else if (nums[mid] == target) {
    
    
            // 别返回,锁定右侧边界
            left = mid + 1;
        }
    }
    // 此时 left - 1 索引越界
    if (left - 1 < 0) return -1;
    // 判断一下 nums[left] 是不是 target
    return nums[left - 1] == target ? (left - 1) : -1;
}

滑动窗口 https://labuladong.gitee.io/algo/di-ling-zh-bfe1b/wo-xie-le–f02cd/

/* 滑动窗口算法框架 */
void slidingWindow(string s) {
    
    
    unordered_map<char, int> window;
    
    int left = 0, right = 0;
    while (right < s.size()) {
    
    
        // c 是将移入窗口的字符
        char c = s[right];
        // 增大窗口
        right++;
        // 进行窗口内数据的一系列更新
        ...

        /*** debug 输出的位置 ***/
        // 注意在最终的解法代码中不要 print
        // 因为 IO 操作很耗时,可能导致超时
        printf("window: [%d, %d)\n", left, right);
        /********************/
        
        // 判断左侧窗口是否要收缩
        while (window needs shrink) {
    
    
            // d 是将移出窗口的字符
            char d = s[left];
            // 缩小窗口
            left++;
            // 进行窗口内数据的一系列更新
            ...
        }
    }
}

猜你喜欢

转载自blog.csdn.net/a13821684483/article/details/129832085