leetcode刷题最新篇

基本运算器I

给定一个包含正整数、加(+)、减(-)、乘(* )、除(/)的算数表达式(括号除外),计算其结果。
表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。

class Solution {
public:
    int calculate(string s) {
        stack<int> ops;
        ops.push(1);
        int sign = 1;
        int ret = 0;
        int n = s.length();
        int i = 0;
        while(i < n){
            if(s[i] == ' '){
                i++;
            }
            else if(s[i] == '+'){
                sign = ops.top();
                i++;
            }
            else if(s[i] == '-'){
                sign = -ops.top();
                i++;
            }
            else if(s[i] == '('){
                ops.push(sign);
                i++;
            }
            else if(s[i] == ')'){
                ops.pop();
                i++;
            }
            else{
                long num = 0;
                while(i < n && s[i] >= '0' && s[i] <= '9'){
                    num = num * 10 + s[i] - '0';
                    i++;
                }
                ret += sign * num;
            }
        }
        return ret;
    }
};

基本运算器II

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
例如:(1+(4+5+2)-3)+(6+8)

class Solution {
public:
    int calculate(string s) {
        stack<int> ops;
        ops.push(1);
        int sign = 1;
        int ret = 0;
        int n = s.length();
        int i = 0;
        while(i < n){
            if(s[i] == ' '){
                i++;
            }
            else if(s[i] == '+'){
                sign = ops.top();
                i++;
            }
            else if(s[i] == '-'){
                sign = -ops.top();
                i++;
            }
            else if(s[i] == '('){
                ops.push(sign);
                i++;
            }
            else if(s[i] == ')'){
                ops.pop();
                i++;
            }
            else{
                long num = 0;
                while(i < n && s[i] >= '0' && s[i] <= '9'){
                    num = num * 10 + s[i] - '0';
                    i++;
                }
                ret += sign * num;
            }
        }
        return ret;
    }
};

动态规划

整数拆分

给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积 。

class Solution {
public:
    int integerBreak(int n) {
        vector<int> dp(n, 1);
        for(int i = 1; i < n; i++){
            for(int j = 2; j <= i; j++){
                dp[i] = max(dp[i], dp[i-j] * j);
                dp[i] = max(dp[i], (i-j+1) * j);
            }
        }
        return dp[n-1];
    }
};

最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.size();
        int res = 0, maxlen = 0;
        vector<vector<bool>> dp(n, vector<bool>(n));
        for(int len = 1; len <= n; len++){
            for(int j = 0; j < n-len+1; j++){
                if(len <= 2){
                    dp[j][j+len-1] = s[j] == s[j+len-1];
                }
                else if(s[j] == s[j+len-1]){
                    dp[j][j+len-1] = dp[j+1][j+len-2];
                }
                if(dp[j][j+len-1] && len > maxlen){
                    maxlen = len;
                    res = j;
                }
            }
        }
        return s.substr(res, maxlen);
    }
};

最长有效括号

给你一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长有效(格式正确且连续)括号
子串的长度。

class Solution {
public:
    int longestValidParentheses(string s) {
        int n = s.size();
        vector<int> dp(n+1, 0);
        int res = 0;
        for(int i = 1; i < n; i++){
            if(s[i] == ')' && s[i-1] == '('){
                dp[i+1] = max(dp[i+1], dp[i-1]+2);
            }
            if(s[i] == ')' && s[i-1] == ')' && i >= dp[i]+1 && s[i-dp[i]-1] == '('){
                dp[i+1] = max(dp[i+1], dp[i - dp[i] - 1] + dp[i] + 2);
            }
            res = max(res, dp[i+1]);
        }
        return res;
    }
};

链表

反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* tail = head;
        if(!tail){
            return head;
        }
        while(tail->next){
            ListNode* temp = tail->next;
            tail->next = tail->next->next;
            temp->next = head;
            head = temp;
        }
        return head;
    }
};

环形链表 II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        unordered_set<ListNode*> set;
        while(head){
            if(set.count(head)){
                return head;
            }
            set.insert(head);
            head = head->next;
        }
        return NULL;
    }
};

LRU缓存

请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。
实现 LRUCache 类:

LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字 key 已经存在,则变更其数据值 value ;如果不存在,则向缓存中插入该组 key-value 。如果插入操作导致关键字数量超过 capacity ,则应该 逐出 最久未使用的关键字。

函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。

个人想法:直接对vector进行查找,增加操作,(会超时)

class LRUCache {
public:
    vector<vector<int>> v;
    int n;
    LRUCache(int capacity) {
        n = capacity;
    }
    
    int get(int key) {
        for(int i = 0; i < v.size(); i++){
            if(v[i][0] == key){
                vector<int> temp = v[i];
                while(i < v.size()-1){
                    v[i] = v[i+1];
                    i++;
                }
                v[i] = temp;
                return v[i][1];
            }
        }
        return -1;
    }
    
    void put(int key, int value) {
        int flag = 0;
        for(int i = 0; i < v.size(); i++){
            if(v[i][0] == key){
                flag = 1;
                while(i < v.size()-1){
                    v[i] = v[i+1];
                    i++;
                }
                v[i] = {key, value};
            }
        }
        if(flag == 0){
            if(v.size() < n){
                v.push_back({key, value});
            }
            else{
                int i = 0;
                while(i < v.size()-1){
                    v[i] = v[i+1];
                    i++;
                }
                v[i] = {key, value};
            }
        }
    }
};

哈希表+双向链表

struct DLinkedNode{
    int key, value;
    DLinkedNode* prev;
    DLinkedNode* next;
    DLinkedNode():key(0), value(0), prev(nullptr), next(nullptr){}
    DLinkedNode(int _key, int _value): key(_key), value(_value), prev(nullptr), next(nullptr){}
};
class LRUCache {
public:
    unordered_map<int, DLinkedNode*> cache;
    DLinkedNode* head;
    DLinkedNode* tail;
    int size;
    int capacity;
    LRUCache(int _capacity) {
        capacity = _capacity;
        size  = 0;
        head = new DLinkedNode();
        tail = new DLinkedNode();
        head->next = tail;
        tail->prev = head;
    }
    
    int get(int key) {
        if(!cache.count(key)){
            return -1;
        }
        DLinkedNode* node = cache[key];
        moveToHead(node);
        return node->value;
    }
    
    void put(int key, int value) {
        if(!cache.count(key)){
            DLinkedNode* node = new DLinkedNode(key, value);
            cache[key] = node;
            addToHead(node);
            size++;
            if(size > capacity){
                DLinkedNode* removed = removeTail();
                cache.erase(removed->key);
                delete removed;
                size--;
            }
        }
        else{
            DLinkedNode* node = cache[key];
            node->value = value;
            moveToHead(node);
        }
    }
    void addToHead(DLinkedNode* node){
        node->prev = head;
        node->next = head->next;
        head->next->prev = node;
        head->next = node;
    }
    void removeNode(DLinkedNode* node){
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }
    void moveToHead(DLinkedNode* node){
        removeNode(node);
        addToHead(node);
    }
    DLinkedNode* removeTail(){
        DLinkedNode* node = tail->prev;
        removeNode(node);
        return node;
    }
};

二叉树

二叉树的中序遍历

递归

class Solution {
public:
    void helper(TreeNode* root, vector<int>& v){
        if(root == nullptr){
            return;
        }
        helper(root->left, v);
        v.push_back(root->val);
        helper(root->right, v);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        helper(root, res);
        return res;
    }
};

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> stk;
        while(root != nullptr || !stk.empty()){
            while(root != nullptr){
                stk.push(root);
                root = root->left;
            }
            root = stk.top();
            stk.pop();
            res.push_back(root->val);
            root = root->right;
        }
        return res;
    }
};

二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

class Solution {
public:
    TreeNode* ans;
    bool dfs(TreeNode* root, TreeNode* p, TreeNode* q){
        if(root == NULL){
            return false;
        }
        bool lson = dfs(root->left, p, q);
        bool rson = dfs(root->right, p, q);
        if((lson && rson) || ((root->val == p->val || root->val == q->val) &&(lson || rson))){
            ans = root;
        }
        return lson || rson ||(root->val == p->val || root->val == q->val);
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        dfs(root, p, q);
        return ans;
    }
};

滑动窗口

无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        unordered_set<char> set;
        int left = 0;
        int res = 0;
        for(int i = 0; i < s.size(); i++){
            while(set.count(s[i])){
                set.erase(s[left]);
                left++;
            }
            set.insert(s[i]);
            res = max(res, i - left + 1);
        }
        return res;
    }
};
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

猫头丁

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

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

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

打赏作者

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

抵扣说明:

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

余额充值