Giter VIP home page Giter VIP logo

leetcode-2020's Introduction

LeetCode-2020

马上进入2020找实习冲刺阶段,我决定以天为单位,记录每天做的LeetCode习题,方便后期整理。

C++文档神器推荐:cppreference.chm

1 LeetCode刷题记录(每日更新)

📅 更新打卡:2020 - week2 - 3/13

2 各难度典型题目汇总

3 其他刷题项目

3.1 Daily Problem

(这是另一个每日刷题项目,有空的时候我也会更新)

3.2 剑指Offer

总结整理剑指Offer中部分经典题目

4 常用解题方法总结

4.1 并查集

并查集是一种树形数据结构,用于处理一些非连通子图的合并以及查询问题,主要使用Union以及find两个方法定义了该数据结构的相关操作:

  • Find:确定给定元素属于哪个子集,可以用于确定两个元素是否属于同一个子集;
  • Union:将两个子集合并成同一个集合。

并查集核心代码:

class UnionSet(object):
    def __init__(self, n, init_list = None):
        if init_list:
            self.parent = init_list
        else:
            self.parent = [i for i in range(n)]
    
    def __str__(self):
        return str(self.parent)
    
    # 不带路径压缩的find函数
    def find(self, num):
        if self.parent[num] == num:
            return self.parent[num]
        return self.find(self.parent[num])
       
    # 带路径压缩的find函数:在执行find函数的时候完成路径压缩
    def find(self, num):
        root = num
        while root != self.parent[root]:
            root = self.parent[root]
        while num != root:
            self.parent[num], num = root, self.parent[num]
        return root
    
    def union(self, num1, num2):
        self.parent[self.find(num1)] = self.find(num2)

    def count(self):
        return len([1 for i, num in enumerate(self.parent) if num == i])

并查集经典题目:

4.2 位运算

检查数x是否为2的幂:

x > 0 and x & (x - 1) == 0

将最右边一位1置0:

num = num & (num - 1)

4.3 二叉树遍历

层序遍历:

python

def levelOrder(root):
        if not root:
            return []
        ans = []
        queue = [root]
        while queue:
            count = len(queue)
            cur_line = []
            while count:
                cur = queue.pop(0)
                cur_line.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
                count -= 1
            ans.append(cur_line)
        return ans

cpp

vector<vector<int>> levelOrder(TreeNode* root) {
    vector<vector<int>> ret;
    if (root == NULL) return ret;

    queue<TreeNode*> que;
    que.push(root);
    while (!que.empty()) {
        int counter = que.size();
        vector<int> cur_row;
        while (counter--) {
            TreeNode* cur = que.front();
            que.pop();
            cur_row.push_back(cur->val);
            if (cur->left) que.push(cur->left);
            if (cur->right) que.push(cur->right);
        }
        ret.push_back(cur_row);
    }
    return ret;
}

前序遍历非递归写法:

python

def preOrder(root):
	if not root:
        return []
    ans = []
    stack = [root]
    while stack:
        cur = stack.pop()
        ans.append(cur.val)
        # 这里注意了,是先访问右节点
        if cur.right:
            stack.append(cur.right)
        if cur.left:
            stack.append(cur.left)
    return ans

Cpp

vector<int> preorderTraversal(TreeNode* root) {
    vector<int> ret;
    if (root == NULL) return ret;

    stack<TreeNode*> st;
    st.push(root);
    while (!st.empty()) {
        TreeNode* cur = st.top();
        st.pop();
        ret.push_back(cur->val);
        if (cur->right) st.push(cur->right);
        if (cur->left) st.push(cur->left);
    }
    return ret;
}

中序遍历的非递归写法:

*中序遍历递归写法将左右子节点递归的顺序反过来就能得到逆序。

python

def inOrder(root):
	ans = []
	stack = []
    cur = root
	while cur or stack:
		if cur:
			stack.append(cur.left)
            cur = cur.left
		else:
			cur = stack.pop()
			ans.append(cur.val)
			cur = cur.right
	return ans

cpp

vector<int> inorderTraversal(TreeNode* root) {
    vector<int> ret;
    stack<TreeNode*> st;
    TreeNode* cur = root;
    while (cur || !st.empty()) {
        if (cur) {
            st.push(cur);
            cur = cur->left;
        }
        else {
            cur = st.top();
            st.pop();
            ret.push_back(cur->val);
            cur = cur->right;
        }
    }
    return ret;
}

后序遍历的非递归写法:

python

# 从根节点开始依次迭代,弹出栈顶元素输出到输出列表中,然后依次压入它的所有孩子节点,按照从上到下、从左至右的顺序依次压入栈中。因为深度优先搜索后序遍历的顺序是从下到上、从左至右,所以需要将输出列表逆序输出。

def postOrder(root):
	if not root:
        return []
    ans = []
    stack = [root]
    while stack:
        cur = stack.pop()
        ans.append(cur.val)
        if cur.left:
            stack.append(cur.left)
        if cur.right:
            stack.append(cur.right)
    return ans[::-1]

cpp

vector<int> postorderTraversal(TreeNode* root) {
    vector<int> ret;
    if (root == NULL) return ret;

    stack<TreeNode*> st;
    st.push(root);
    while (!st.empty()) {
        TreeNode* cur = st.top();
        st.pop();
        ret.push_back(cur->val);
        if (cur->left) st.push(cur->left);
        if (cur->right) st.push(cur->right);
    }

    reverse(ret.begin(), ret.end());
    return ret;
}

4.4 排序算法

十大经典排序算法 概览截图

冒泡排序:

void bubbleSort(vector<int>& vec) {
    int n = vec.size();
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (vec[j + 1] < vec[j]) swap(vec[j + 1], vec[j]);
        }
    }
}

插入排序:

void insertSort(vector<int>& vec) {
	for (int i = 1; i < vec.size(); i++) {
		int cur = vec[i];
		for (int j = i - 1; j >= 0; j--) {
			if (vec[j] > vec[j + 1]) 
                swap(vec[j + 1], vec[j]);
			else break;
		}
	}
}

选择排序:

void selectSort(vector<int>& vec) {
	for (int i = 0; i < vec.size(); i++) {
		int temp_min = vec[i], temp_min_idx = i;
		for (int j = i + 1; j < vec.size(); j++) {
			if (vec[j] < temp_min) {
				temp_min = vec[j];
				temp_min_idx = j;
			}
		}
		swap(vec[i], vec[temp_min_idx]);
	}
}

快速排序:

// 版本1:快慢指针,从左往右遍历
void quick_sort1(vector<int>& vec, int left, int right) {
	if (left >= right) return;
	
	int ptr = left, pivot = vec[ptr];
	for (int i = left + 1; i <= right; i++) {
		if (vec[i] < pivot) {
			ptr ++;
			swap(vec[ptr], vec[i]);
		}
	}
	swap(vec[left], vec[ptr]);

	quick_sort1(vec, left, ptr - 1);
	quick_sort1(vec, ptr + 1, right);

}

// 版本2:前后指针,最经典的方法
void quick_sort2(vector<int>& vec, int left, int right) {
	if (left >= right) return;

	int pivot = vec[left];
	int l = left, r = right;
	while (left < right) {
		while (left < right && vec[right] >= pivot) right --;
		while (left < right && vec[left] <= pivot) left ++;
		swap(vec[left], vec[right]);
	}
	swap(vec[left], vec[l]);

	quick_sort2(vec, l, left - 1);
	quick_sort2(vec, left + 1, r);
}

void quickSort(vector<int>& vec) {
	quick_sort2(vec, 0, vec.size() - 1);
}

归并排序:

void merge_sort(vector<int>& vec, int left, int right) {
	if (right <= left) return;

	int mid = left + (right - left) / 2;
	merge_sort(vec, left, mid);
	merge_sort(vec, mid + 1, right);

	int ptr1 = left, ptr2 = mid + 1;
	vector<int> temp;
	while (ptr1 <= mid && ptr2 <= right) {
		if (vec[ptr1] <= vec[ptr2]) {
			temp.push_back(vec[ptr1]);
			ptr1 ++;
		}
		else {
			temp.push_back(vec[ptr2]);
			ptr2 ++;
		}
	}
	while (ptr1 <= mid) temp.push_back(vec[ptr1++]);
	while (ptr2 <= right) temp.push_back(vec[ptr2++]);
	for (int i = 0; i < temp.size(); i++) {
		vec[left + i] = temp[i];
	}
}

void mergeSort(vector<int>& vec) {
	merge_sort(vec, 0, vec.size() - 1);
}

4.5 BFS&DFS

BFS解题模板:

DFS解题模板:

4.6 最小公倍数&最大公约数

最小公倍数辗转相除法:

int gcd(int a, int b) {
	if (a < b) { a = a ^ b; b = a ^ b; a = a ^ b; }
    return b == 0 ? a : gcd(b, a % b);
}

最大公约数求法:

int lcm(int a, int b) {
    return a * b / gcd(a, b);
}

4.7 前缀树

前缀树在字符串查找、输入框自动补全等应用场所常常使用。

class Trie {
private:
    // 定义前缀树结构体,有两个成员变量
    // isEnd:表示是否存在从根节点到当前节点的字符串
    // children:表示当前节点的26个子节点
    struct TrieNode {
        TrieNode() : isEnd(false), children(26, nullptr) {}
        ~TrieNode() {
            for (auto child : children) 
                if (child) delete child;
        }

        bool isEnd;
        vector<TrieNode*> children;
    };

    // 定义根节点
    TrieNode *root;
    
public:
    /** Initialize your data structure here. */
    Trie() : root(new TrieNode()) {}
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        TrieNode* cur = root;
        for (auto ch : word) {
            if (cur->children[ch - 'a'] == nullptr) {
                cur->children[ch - 'a'] = new TrieNode();
            }
            cur = cur->children[ch - 'a'];
        }
        cur->isEnd = true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        TrieNode* cur = root;
        for (auto ch : word) {
            if (cur->children[ch - 'a'] == nullptr) return false;
            cur = cur->children[ch - 'a'];
        }
        return cur->isEnd;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        TrieNode* cur = root;
        for (auto ch : prefix) {
            if (cur->children[ch - 'a'] == nullptr) return false;
            cur = cur->children[ch - 'a'];
        }
        return true;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie* obj = new Trie();
 * obj->insert(word);
 * bool param_2 = obj->search(word);
 * bool param_3 = obj->startsWith(prefix);
 */

5 题目分门别类(TODO):

算法类

数据结构类

系列问题

Top题目进度

  • Top 100 Linked Questions [0%]
  • Top Interview Questions [0%]

优秀LeetCode题解传送门:https://github.com/wonanut/leetcode

目录

leetcode-2020's People

Contributors

wonanut avatar

Stargazers

FakeNews avatar Yaya avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.