Leetcode易考总结

每日背诵,

  1. 中序遍历非递归
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> sta;
        vector<int> res;
        if(root) sta.push(root);
        while(!sta.empty()) {
            TreeNode* node = sta.top();
            if(node == NULL) {
                sta.pop();//吐出标志位
                node = sta.top();
                sta.pop();
                res.emplace_back(node->val);//吐出标志位后的node
            }
            else {
                sta.pop();//先吐出,稍后再放入
                if(node->right) sta.push(node->right);//右孩子先入栈

                sta.push(node);//前序遍历移动这个的位置
                sta.push(NULL);
                
                if(node->left) sta.push(node->left);
            }
        }
        return res;
    }
};
  1. 快排
class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        srand(time(0));
        quickSort(nums, 0, nums.size()-1);
        return nums;
    }
    void quickSort(vector<int>& nums, int left, int right) {
        if(left >= right) return;//***
        int mid = partition(nums, left, right);
        quickSort(nums, left, mid-1);
        quickSort(nums, mid+1, right);
    }
    int partition(vector<int>& nums, int left, int right) {
        int point = rand()%(right-left+1) +left;
        swap(nums[left],nums[point]);
        int local = left;
        while(left < right) {
            while(left < right && nums[right] >= nums[local]) right--; //向左移动到第一个比基准值小的点
            while(left < right && nums[left] <= nums[local]) left++;
            if(left < right) swap(nums[left],nums[right]);
        }
        swap(nums[local],nums[left]);//将基准值放到中间
        return left;
    }
};
  1. KMP
class Solution {
public:
    int strStr(string haystack, string needle) {
        int m = haystack.size();
        int n = needle.size();
        if(n == 0) return 0;
        if(m == 0) return -1;
        vector<int> next(n,0);
        getNext(next,needle);
        for(int i = 0,j = 0;i < m;i++) {
            while(j > 0 && needle[j] != haystack[i]) {
                j = next[j-1];
            }
            if(needle[j] == haystack[i]) j++;
            if(j == n) return i-n+1;
        }
        return -1;
        
    }
    void getNext(vector<int>& next,string s) {
        for(int i = 1,j = 0;i<s.size();i++) {
            while(j > 0 && s[j] != s[i]) {
                j = next[j-1];//因为当next[j] != 0时,当前j前面几个字符和前缀字符相同,可以直接从前缀的下一位比较
                          //直到j = 0或者s[j] == s[i]
            }
            if(s[j] == s[i]) j++;
            next[i] = j;
        }
    }
};

请添加图片描述

  1. 背包问题

01背包:416. 分割等和子集 474. 一和零 494. 目标和 879. 盈利计划 1049. 最后一块石头的重量 II 1230. 抛掷硬币

先遍历物品,再遍历背包,二维数组

//求最大能装多少价值
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
//求有多少种组合/排列
dp[i][j] = dp[i-1][j];//首先等于前i-1种物品能凑成j的方式
if(j >= nums[i-1]) //一维数组的话,直接从weight开始
   dp[i][j] += dp[i-1][j-nums[i-1]];//再加上前i-1种物品能凑出j-nums[i]的方式

完全背包:1449. 数位成本和为目标值的最大数字 322. 零钱兑换 518. 零钱兑换 II 279. 完全平方数
377. 组合总和 Ⅳ

一维数组,从前到后遍历
若先遍历物品,虽然每个物品有无限个,但是物品之间有先后顺序,是计算组合
若先遍历背包容量,物品之间无序(在下一次大循环中前面的物品重新放入),是计算排列

两种背包code的区别:
0-1背包:二维数组,第一行和第一列都需要初始化,需要nums+1行和bagSize+1列
若使用一维数组,后遍历的需要从后向前
遍历中需要判断当前的bagSize是否比当前物品的weight重
完全背包:使用一维数组,第一个元素初始化,需要bagSize+1列 ,从前往后。

  1. 前缀和
    常见于求连续子数组,后边的前缀和减前边的前缀和就是中间数组的和,若求长度,需要用map存前面的下标
    例:二维子矩阵的和,0 和 1 个数相同的子数组,和为 k 的子数组
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值