Leetcode模板

C++

Posted by PZ on December 16, 2019

Trees - Linked


//Definition for a binary tree node.
struct TreeNode {
      int val;
      TreeNode *left;
      TreeNode *right;
      TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  };

Linked List Construction

  //Definition for singly-linked list.
  struct ListNode {
      int val;
      ListNode *next;
      ListNode(int x) : val(x), next(NULL) {}
  };

Tips:

Linked List Problems Mostly relate to Recursion, especially Trees (BST)

Canonical Problems:

LeetCode 206. Reverse Linked List:

Iteration

class Solution {
public:
  ListNode* reverseList(ListNode* head) {
    ListNode* prev = nullptr;
    ListNode* curr = head;
    ListNode* next;
    while (curr) {
      next = curr->next;
      curr->next = prev;
      prev = curr;
      curr = next;
    }
    return prev;
  }
};

Recursion

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
       if (!head || !(head->next)) return head;
       ListNode* tmp = head -> next;
       ListNode* newNode = reverseList(tmp);
       tmp->next = head;
       head->next = NULL;
       return newNode;
    }
};

二分模板

// Returns the smallest m in [l, r),
// s.t. cond(m) == True
// If not found returns r.
def binary_search(l, r, cond)
  while l < r:
    m = l + (r - l) // 2
    if cond(m):
      r = m
    else
      l = m + 1
  return l  

Recursion 模板

def function(int a){
    if cal[a] is True:## memoriztion
        return cal[a]
    #do something with function(a-1)
    cal[a] = function(a-1)+a
    return cal[a]
}

排列模板

def P(n, m, cur, used):
  if len(cur) == m:
    print(cur)
    return
  for i in range(n):
    if used[i]: continue
    used[i] = True
    cur.append(i + 1)
    P(n, m, cur, used)
    cur.pop()
    used[i] = False
n = 5
m = 3
P(n, m, [], [False] * n)

组合模板

def C(n, m, s, cur):
  if len(cur) == m:
    print(cur)
    return
  for i in range(s, n):
    cur.append(i + 1)
    C(n, m, i + 1, cur)
    cur.pop()    
n = 5
m = 3
C(n, m, 0, [])

DFS

Notes:

DFS function:

  1. when void: do not need to deal with returning some value, just focusing on when to finish.
  2. when some value (like boolean), needs to consider what to return when some condition happens.

DFS: for all neighbors: if (unvisited) DFS();

// Check whether there is a path from |start| to |target| in graph G.
// neighbor(x) returns the neighbors of x in G.
seen = set([start])
def dfs(n):
  if n == target:
    return True  
  for t in neighbor(n):
    if t in seen: continue
    seen.add(t)
    if dfs(t): return True
    seen.remove(t) # back-tracking  
  return False
return dfs(start)

DFS Examples: 737. Sentence Similarity II

class Solution {
public:
    bool areSentencesSimilarTwo(vector<string>& words1, vector<string>& words2, vector<pair<string, string>> pairs) {
        if (words1.size() != words2.size()) return false;
        unordered_map<string, unordered_set<string>> p;
        for (auto &vp : pairs) {
            p[vp.first].emplace(vp.second);
            p[vp.second].emplace(vp.first);
        }
        for (int i = 0; i < words1.size(); i++) {
            unordered_set<string> visited;
            if (isSimilar(words1[i], words2[i], p, visited)) continue;
            else return false;
        }
        return true;
    }
    
    bool isSimilar(string& s1, string& s2, unordered_map<string, unordered_set<string>>& p, unordered_set<string>& visited) {
        if (s1 == s2) return true;
        
        visited.emplace(s1);
        for (auto s : p[s1]) {
            if (!visited.count(s) && isSimilar(s, s2, p, visited))
                return true;
        }
        
        return false;
    }
};

DFS Examples: 200. Number of Islands

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        if (grid.empty()) return 0;
        int m = grid.size();
        int n = grid[0].size();
        int num = 0;
        for (int i = 0; i < m; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                if (grid[i][j] == '1')
                {
                    DFS(m,n,i,j,grid);
                    num += 1;
                }
            }
        }
        return num;
        
    }
private:    
    void DFS(int m, int n,int r, int c,vector<vector<char>>& grid)
    {
        if (r < 0 || c < 0 || r >= m || c >= n || grid[r][c] == '0') return;
        grid[r][c] = '0';
        DFS(m,n,r+1,c,grid);
        DFS(m,n,r-1,c,grid);
        DFS(m,n,r,c+1,grid);
        DFS(m,n,r,c-1,grid);        
    }
};

BFS

// Find the shortest path from |start| to |target| in a unweighted graph G.
// neighbor(x) returns the neighbors of x in G.
q = deque([start])
seen = set([start])
steps = 0
while q:
  size = len(q)
  for _ in range(size):
    n = q.popleft()
    if n == target: return steps
    for t in neighbor(n):
      if t in seen: continue
      q.append(t)
      seen.add(t)
  steps += 1
return -1 # not found

滚动数组DP模板

void function(N, matrix,m,n)
{
	intilize;
	vector<vector<int>> dp(...);
	for (int k = 0; k < N; ++k)// how many times
	{
		vector<vector<int>> tmp(...);
		for (int i = 0; i < m; ++i)
		{
			for (int j = 0; j < n; ++j)
			{
				/* code */
			}
		}
		dp.swap(tmp);
	}
	return ...;
}

Word Matching DP – 单词 从后往前

class Solution {
public:
    bool isMatch(string s, string p) {
        int n1 = s.size();
        int n2 = p.size();
        vector<vector<int>> dp(n1+1,vector<int>(n2+1,0));
        dp[0][0] = 1;
	// Initialization
        for (int i = 1; i <= n1; ++i)
        {
            dp[i][0] = 0;
        }
        for (int j = 1; j <= n2; ++j)
        {
            if (p[j-1] == '*')
            {
                dp[0][j] = dp[0][j-2];
            }
            else
            {
                dp[0][j] = 0;
            }
        }
	// 分情况讨论
        for (int i = 1; i <= n1; ++i)
        {
            for (int j = 1; j <= n2; ++j)
            {
                if (p[j-1] != '.' && p[j-1] != '*')
                {
                    if (s[i-1] != p[j-1])
                    {
                        dp[i][j] = 0;
                    }
                    else
                    {
                        dp[i][j] = dp[i-1][j-1];
                    }
                }
                else if (p[j-1] == '.')
                {
                    dp[i][j] = dp[i-1][j-1];
                }
                else if (j >= 2)
                {
                    if (p[j-2] == s[i-1])
                    {
                        dp[i][j] = (dp[i-1][j-2] || dp[i][j-2] || dp[i-1][j]);
                    }
                    else if (p[j-2] != '.')
                    {
                        dp[i][j] = dp[i][j-2];
                    }
                    else
                    {
                        dp[i][j] = (dp[i-1][j-2] || dp[i][j-2] || dp[i-1][j]);
                    }
                }
            }
        }
        return dp[n1][n2] > 0 ? true:false;
    }
};

Binary Tree Traversal 模板

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
       order(root);
       return ans;
    } 
private:
    void order(TreeNode* root)
    {
    	if (root == NULL)
        {
            return;
        }
        order(root -> left);
        order(root -> right);
        ans.push_back(root-> val);
        return; 
    }
    vector<int> ans;
};

Save Memory of run-time stack;


前缀树模板

class Trie(object):
  def __init__(self): self.root = {}
  def insert(self, word):
    p = self.root
    for c in word:
      if c not in p: p[c] = {}
      p = p[c]
    p['#'] = True    
  def search(self, word):
    node = self._find(word)
    return node and '#' in node
    
  def startsWith(self, prefix):
    return self._find(prefix)
  def _find(self, prefix):
    p = self.root
    for c in prefix:
      if c not in p: return None
      p = p[c]
    return p
    

Union Find

// Author: Huahua
class UnionFindSet {
public:
    UnionFindSet(int n) {
        ranks_ = vector<int>(n + 1, 0);        
        parents_ = vector<int>(n + 1, 0);                
        
        for (int i = 0; i < parents_.size(); ++i)
            parents_[i] = i;
    }
    
    // Merge sets that contains u and v.
    // Return true if merged, false if u and v are already in one set.
    bool Union(int u, int v) {
        int pu = Find(u);
        int pv = Find(v);
        if (pu == pv) return false;
        
        // Meger low rank tree into high rank tree
        if (ranks_[pv] < ranks_[pu])
            parents_[pv] = pu;           
        else if (ranks_[pu] < ranks_[pv])
            parents_[pu] = pv;
        else {
            parents_[pv] = pu;
            ranks_[pu] += 1;
        }
        
        return true;
    }
    
    // Get the root of u.
    int Find(int u) {        
        // Compress the path during traversal
        if (u != parents_[u])
            parents_[u] = Find(parents_[u]);        
        return parents_[u];
    }
private:
    vector<int> parents_;
    vector<int> ranks_;
};

Explanation

UFS1 UFS2 UFS3

Examples:

-花花酱 LeetCode 547. Friend Circles -花花酱 LeetCode 737. Sentence Similarity II -花花酱 LeetCode 684. Redundant Connection