leetcode刷题笔记

记录自己刷算法题遇见的美妙解法

动态规划(dynamic programming)的programming指的是一种表格法,而非编写计算机程序

【leetcode 104】二叉树最大深度

    int maxDepth(TreeNode* root) {
        if(root==nullptr){
            return 0;
        }
        int left = maxDepth(root->left);
        int right = maxDepth(root->right);
        return (left>right?left:right)+1;
    }

【leetcode 100】判断二叉树是否相同,好简单,好美妙的解法

/**
 * 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:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if (p == NULL) return q == NULL;
            return q != NULL && p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
    }
};

反转链表

    // 递归版本
    ListNode* reverseList(ListNode* head) {
        if(head == NULL || head->next == NULL){
            return head;
        }
        ListNode* last = reverseList(head->next);
        head->next->next=head;
        head->next = NULL;
        return last;
    }
    // 迭代版本
    ListNode* reverseList(ListNode* head) {
        if(head == nullptr || head->next==nullptr) return head;

        ListNode *pre = nullptr, *cur = head;

        while(cur){
            ListNode *next = cur->next;
            cur->next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }

是否为环形链表,除了使用哈希表来判断,也可以使用快慢指针,如果快慢指针相遇,即代表链表有环

class Solution {
public:
    bool hasCycle(ListNode* head) {
        if (head == nullptr || head->next == nullptr) {
            return false;
        }
        ListNode* slow = head;
        ListNode* fast = head->next;
        while (slow != fast) {
            if (fast == nullptr || fast->next == nullptr) {
                return false;
            }
            slow = slow->next;
            fast = fast->next->next;
        }
        return true;
    }
};

392. 判断子序列

判断s是否为t的子序列,

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int n = s.length(), m = t.length();
        int i = 0, j = 0;
        while (i < n && j < m) {
            if (s[i] == t[j]) {
                i++;
            }
            j++;
        }
        return i == n;
    }
};

解数独:本质上就是穷举,不过要使用回溯法,运用计算机递归调用机制

class Solution {
public:
    bool isValid(vector<vector<char>>& board, int r,int c,char n){
        for(int i=0;i<9;i++){
            if(board[r][i] == n) return false;
            if(board[i][c] == n) return false;
            if(board[(r/3)*3+i/3][(c/3)*3+i%3] == n) return false;
        }
        return true;
    }
    bool backtrack(vector<vector<char>>& board, int i, int j){
        int m=9,n=9;
        if(j==n){
            return backtrack(board, i+1, 0);
            
        }
        if(i==m){
            return true;
        }
        if(board[i][j]!='.'){
            return backtrack(board, i,j+1);
        }

        for(char ch = '1';ch<='9';ch++){
            if(!isValid(board, i, j, ch)) continue;

            board[i][j] = ch;
            if(backtrack(board,i,j+1)){
                return true;
            }
            board[i][j]='.';
        }
        return false;
    }
    void solveSudoku(vector<vector<char>>& board) {
        backtrack(board, 0, 0);
    }
};

求最大公约数,欧几里得算法,这也许是世界上已知的最古老的算法之一,上次B站崩溃就是因为使用Lua语言计算gcd时,出现了NAN错误,即not a number,我想如果使用静态语言就不会出现这种情况了吧

int gcd(int a, int b){
    int tmp;
    while(b){
        tmp = b;
        b = a % b;
        a = tmp;
    }
    return a;
}

224 基本计算器

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;
    }
};

二叉树的层序遍历

/**
 * 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<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        if(root==NULL)
            return res;
        queue<TreeNode *> nodes;
        nodes.push(root);
        
        while(!nodes.empty()){
            int size = nodes.size();
            vector<int> layer;
            for(int i=0;i<size;i++){
                TreeNode* tmp = nodes.front();
                nodes.pop();
                layer.push_back(tmp->val);
                if(tmp->left!=NULL)
                    nodes.push(tmp->left);
                if(tmp->right!=NULL)
                    nodes.push(tmp->right);
            }
            res.push_back(layer);
        }     
        return res;
    }
};

合并K个有序链表,先看怎么合并两个有序链表,然后k个直接新建一个空指针,然后依次合并。

合并两个有序链表时,新建一个虚拟头结点,然后指向两个链表中的最小值,最后再让当前指针指向未遍历完的链表。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode *head = nullptr;
        for(int i=0;i<lists.size();i++){
            head = mergetTwoLists(head, lists[i]);
        }
        return head;
    }

    ListNode *mergetTwoLists(ListNode *l1, ListNode *l2){
        if(!l1 || !l2) return l1?l1:l2;

        ListNode head ;
        ListNode *cur = &head;
        while(l1 && l2){
            if(l1->val < l2->val){
                cur->next = l1;
                l1=l1->next;
            }
            else{
                cur->next = l2;
                l2=l2->next;
            }
            cur = cur->next;
        }

        cur->next = l1?l1:l2;
        return head.next;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值