leetcode笔记—Hash Table

1. Two Sum (easy)

找到数组中和为target的两个数,返回索引

problem
View Code

 


3. Longest Substr Without Repeating Characters (medium)

最长的无重复的子字符串

problem
View Code

 


 

18. 4Sum (medium)

找到所有和为target的四元数组

problem
View Code

 


30. Substring with Concatenation of All Words (hard) #

查找字符串,子串为words的组合

problem
View Code

 


36. Valid Sudoku (medium) #

判断数独矩阵是否有效

Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:

Each row must contain the digits 1-9 without repetition.
Each column must contain the digits 1-9 without repetition.
Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition.

A partially filled sudoku which is valid.

The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

Example 1:

Input:
[
  ["5","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
Output: true
Example 2:

Input:
[
  ["8","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
Output: false
Explanation: Same as Example 1, except with the 5 in the top left corner being 
    modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid.
Note:

A Sudoku board (partially filled) could be valid but is not necessarily solvable.
Only the filled cells need to be validated according to the mentioned rules.
The given board contain only digits 1-9 and the character '.'.
The given board size is always 9x9.
problem
 1 class Solution {
 2 public:
 3     bool isValidSudoku(vector<vector<char>>& board) {
 4         vector<vector<bool>> row(9, vector<bool>(9, false));
 5         vector<vector<bool>> col(9, vector<bool>(9, false));
 6         vector<vector<bool>> box(9, vector<bool>(9, false));
 7         for (int i = 0; i < 9; ++i) {
 8             for (int j = 0; j < 9; ++j) {
 9                 if (board[i][j] != '.') {
10                     int num = board[i][j] - '0' - 1, boxNum = i/3*3 + j/3;
11                     if (row[i][num] || col[j][num] || box[boxNum][num])
12                         return false;
13                     row[i][num] = col[j][num] = box[boxNum][num] = true;
14                 }
15             }
16         }
17         return true;
18     }
19 };
View Code

 


37. Sudoku Solver (hard) #

解出数独答案

Write a program to solve a Sudoku puzzle by filling the empty cells.

A sudoku solution must satisfy all of the following rules:

Each of the digits 1-9 must occur exactly once in each row.
Each of the digits 1-9 must occur exactly once in each column.
Each of the the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.
Empty cells are indicated by the character '.'.
Note:

The given board contain only digits 1-9 and the character '.'.
You may assume that the given Sudoku puzzle will have a single unique solution.
The given board size is always 9x9.
problem
 1 // backtracking
 2 class Solution {
 3 public:
 4     void solveSudoku(vector<vector<char>>& board) {
 5         solve(board);
 6     }
 7     bool solve(vector<vector<char>>& board) {
 8         for (int i = 0; i < 9; ++i) {
 9             for (int j = 0; j < 9; ++j) {
10                 if (board[i][j] == '.') {
11                     for (char val = '1'; val <= '9'; ++val) {
12                         if (valid(board, i, j, val)) {
13                             board[i][j] = val;
14                             if (solve(board))
15                                 return true;
16                             board[i][j] = '.';
17                         }
18                     }
19                     return false;
20                 }
21             }
22         }
23         return true;
24     }
25     bool valid(vector<vector<char>>& board, int x, int y, char val) {
26         for (int i = 0; i < 9; ++i) {
27             if (board[x][i] == val)
28                 return false;
29             if (board[i][y] == val)
30                 return false;
31             if (board[3*(x/3) + i/3][3*(y/3) + i%3] == val)
32                 return false;
33         }
34         return true;
35     }
36 };
View Code
 1 // 普通思路解法,不能全部通过
 2 class Solution {
 3 public:
 4     void solveSudoku(vector<vector<char>>& board) {
 5         vector<vector<bool>> flag(3*9, vector<bool>(9, false));
 6         for (int i = 0; i < 9; ++i) {
 7             for (int j = 0; j < 9; ++j) {
 8                 if (board[i][j] != '.') {
 9                     flag[i][board[i][j] - '1'] = true;;
10                     flag[9 + j][board[i][j] - '1'] = true;
11                     flag[18 + 3*(i/3) + j/3][board[i][j] - '1'] = true;
12                 }
13             }
14         }
15         bool change = 1;
16         char val;
17         while (change) {
18             change = false;
19             for (int i = 0; i < 9; ++i) {
20                 for (int j = 0; j < 9; ++j) {
21                     if (board[i][j] == '.' && valid(flag, i, j, val)) {
22                         change = true;
23                         board[i][j] = val + '1';
24                         flag[i][val] = true;;
25                         flag[9 + j][val] = true;
26                         flag[18 + 3*(i/3) + j/3][val] = true;
27                         // cout << i << " " << j << " " << (int)val << endl;
28                     }
29                 }
30             }
31         }
32     }
33     bool valid(vector<vector<bool>>& flag, int x, int y, char& val) {
34         int cnt = 0;
35         for (int i = 0; i < 9; ++i) {
36             if ((!flag[x][i]) && (!flag[y + 9][i]) && (!flag[18 + 3*(x/3) + y/3][i])) {
37                 ++cnt;
38                 val = i;
39             }
40         }
41         // cout << "cnt: " << cnt << " " << x << " " << y << endl;
42         return cnt == 1;
43     }
44 };
View Code

 


49. Group Anagrams (medium)

字符串分组,组成元素一致的分为一组

problem
View Code

 


76. Minimum Window Substring (hard) #

最小的包含某子串的窗口

problem
View Code

 


85. Maximal Rectangle (hard) #

 找到矩阵中,最大的 值全为1的子矩阵

problem
View Code
View Code

 


94. Binary Tree Inorder Traversal (medium)

二叉树的中序遍历

Given a binary tree, return the inorder traversal of its nodes' values.

Example:

Input: [1,null,2,3]
   1
    \
     2
    /
   3

Output: [1,3,2]
Follow up: Recursive solution is trivial, could you do it iteratively?
problem
 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     vector<int> inorderTraversal(TreeNode* root) {
13         vector<int> res;
14         vector<TreeNode*> stack;
15         while (!stack.empty() || root) {
16             if (root) {
17                 stack.push_back(root);
18                 root = root -> left;
19             }
20             else {
21                 root = stack.back();
22                 stack.pop_back();
23                 res.push_back(root -> val);
24                 root = root -> right;
25             }
26         }
27         return res;
28     }
29 };
View Code

 


136. Single Number (easy)

找出只出现一次的数字

Given a non-empty array of integers, every element appears twice except for one. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Example 1:

Input: [2,2,1]
Output: 1
Example 2:

Input: [4,1,2,1,2]
Output: 4
problem
1 class Solution {
2 public:
3     int singleNumber(vector<int>& nums) {
4         int res = 0;
5         for (int n : nums)
6             res ^= n;
7         return res;
8     }
9 };
View Code

 


138. Copy List with Random Pointer (medium) #

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

链表的节点中包含一个指向随机节点的指针,复制这个链表

View Code

 


149. Max Points on a Line (hard) #   待做

在同一条线上的做多的点数

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

Example 1:

Input: [[1,1],[2,2],[3,3]]
Output: 3
Explanation:
^
|
|        o
|     o
|  o  
+------------->
0  1  2  3  4
Example 2:

Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
Output: 4
Explanation:
^
|
|  o
|     o        o
|        o
|  o        o
+------------------->
0  1  2  3  4  5  6
problem

 


166. Fraction to Recurring Decimal (medium)

两个数相除,返回字符串,循环部分写在小括号里

Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.

If the fractional part is repeating, enclose the repeating part in parentheses.

Example 1:

Input: numerator = 1, denominator = 2
Output: "0.5"
Example 2:

Input: numerator = 2, denominator = 1
Output: "2"
Example 3:

Input: numerator = 2, denominator = 3
Output: "0.(6)"
problem
 1 class Solution {
 2 public:
 3     string fractionToDecimal(int numerator, int denominator) {
 4         int sign = 0;
 5         if (numerator < 0 ^ denominator < 0)
 6             sign = 1;
 7         long long numeratorL = abs((long long)numerator);
 8         long long denominatorL = abs((long long)denominator);
 9         long long fraction = numeratorL%denominatorL, loop = -1;
10         string res = sign == 1 ? "-" : "";
11         res += to_string(numeratorL/denominatorL);
12         vector<int> fractionTmp;
13         unordered_map<int, int> mp;
14         if (fraction != 0)
15             res.push_back('.');
16         for (int i = 0; fraction != 0; ++i) {
17             if (mp.find(fraction) != mp.end()) {
18                 loop = mp[fraction];
19                 break;
20             }
21             mp[fraction] = i;
22             fraction *= 10;
23             fractionTmp.push_back(fraction/denominatorL);
24             fraction %= denominatorL;
25         }
26         for (int i = 0; i < fractionTmp.size(); ++i) {
27             if (i == loop)
28                 res.push_back('(');
29             res.append(to_string(fractionTmp[i]));
30         }
31         if (loop != -1)
32             res.push_back(')');
33         return res;
34     }
35 };
View Code

 


187. Repeated DNA Sequences (medium) #

找出长度为10的重复的字符串

All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.

Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.

Example:

Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"

Output: ["AAAAACCCCC", "CCCCCAAAAA"]
problem
 1 class Solution {
 2 public:
 3     vector<string> findRepeatedDnaSequences(string s) {
 4         vector<string> res;
 5         unordered_map<int, int> mp;
 6         int temp = 0;
 7         for (int i = 0; i < 9; ++i)
 8             temp = temp << 3 | (s[i]&7);
 9         for (int i = 9; i < s.size(); ++i) {
10             temp = temp << 3;
11             temp |= s[i]&7;
12             if (mp[temp&0x3FFFFFFF]++ == 1)
13                 res.push_back(s.substr(i - 9, 10));
14         }
15         return res;
16     }
17 };
View Code

 


202. Happy Number (easy)

Write an algorithm to determine if a number is "happy".

A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers.

Example: 

Input: 19
Output: true
Explanation: 
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
problem
 1 class Solution {
 2 public:
 3     bool isHappy(int n) {
 4         unordered_set<int> st;
 5         while (n != 1) {
 6             st.insert(n);
 7             int tmp = 0;
 8             while (n) {
 9                 tmp += (n%10)*(n%10);
10                 n /= 10;
11             }
12             if (st.find(tmp) != st.end())
13                 return false;
14             n = tmp;
15         }
16         return true;
17     }
18 };
View Code
 1 // 判断链表是否有环的方法,O(1)空间
 2 int digitSquareSum(int n) {
 3     int sum = 0, tmp;
 4     while (n) {
 5         tmp = n % 10;
 6         sum += tmp * tmp;
 7         n /= 10;
 8     }
 9     return sum;
10 }
11 
12 bool isHappy(int n) {
13     int slow, fast;
14     slow = fast = n;
15     do {
16         slow = digitSquareSum(slow);
17         fast = digitSquareSum(fast);
18         fast = digitSquareSum(fast);
19     } while(slow != fast);
20     if (slow == 1) return 1;
21     else return 0;
22 }
View Code

 


204. Count Primes (easy) #

计算n以内的质数个数

Count the number of prime numbers less than a non-negative number, n.

Example:

Input: 10
Output: 4
Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.
problem
 1 // 忽略所有2的倍数
 2 // 从3开始,把i的倍数的map全置true(忽略2的倍数);所以每次只需从i*i开始;
 3 // sqrt(n)之后就不需要修改map了
 4 class Solution {
 5 public:
 6     int countPrimes(int n) {
 7         if (n <= 2) return 0;
 8         int res = 1;
 9         int upper = sqrt(n);
10         vector<bool> map(n, false);
11         for (int i = 3; i < n; i += 2) {
12             if (!map[i]) {
13                 ++res;
14                 if (i > upper) continue;
15                 for (int j = i*i; j < n; j += i*2)
16                     map[j] = true;
17             }
18         }
19         return res;
20     }
21 };
View Code

 


205. Isomorphic Strings (easy)

判断两个string格式是否一致

Given two strings s and t, determine if they are isomorphic.

Two strings are isomorphic if the characters in s can be replaced to get t.

All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself.

Example 1:

Input: s = "egg", t = "add"
Output: true
Example 2:

Input: s = "foo", t = "bar"
Output: false
Example 3:

Input: s = "paper", t = "title"
Output: true
Note:
You may assume both s and t have the same length.
problem
 1 class Solution {
 2 public:
 3     bool isIsomorphic(string s, string t) {
 4         vector<char> maps(256, 0);
 5         vector<char> mapt(256, 0);
 6         for (int i = 0; i < s.size(); ++i) {
 7             if (!maps[s[i]] && !mapt[t[i]]) {
 8                 maps[s[i]] = t[i];
 9                 mapt[t[i]] = s[i];
10             }
11             else if (maps[s[i]] != t[i] || mapt[t[i]] != s[i])
12                 return false;
13         }
14         return true;
15     }
16 };
View Code

 


217. Contains Duplicate (easy)

判断数组是否包含重复元素

Given an array of integers, find if the array contains any duplicates.

Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.

Example 1:

Input: [1,2,3,1]
Output: true
Example 2:

Input: [1,2,3,4]
Output: false
Example 3:

Input: [1,1,1,3,3,4,3,2,4,2]
Output: true
problem
 1 class Solution {
 2 public:
 3     bool containsDuplicate(vector<int>& nums) {
 4         unordered_map<int, int> count_map;
 5         for (int num : nums) {
 6             if (++count_map[num] > 1)
 7                 return true;
 8         }
 9         return false;
10     }
11 };
View Code

 


219. Contains Duplicate II (easy)

判断数组是否包含重复元素,且两个重复元素距离小于等于k

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.

Example 1:

Input: nums = [1,2,3,1], k = 3
Output: true
Example 2:

Input: nums = [1,0,1,1], k = 1
Output: true
Example 3:

Input: nums = [1,2,3,1,2,3], k = 2
Output: false
problem
 1 class Solution {
 2 public:
 3     bool containsNearbyDuplicate(vector<int>& nums, int k) {
 4         unordered_map<int, int> mp;
 5         for (int i = 0; i < nums.size(); ++i) {
 6             if (mp.find(nums[i]) != mp.end() && i - mp[nums[i]] <= k)
 7                 return true;
 8             else
 9                 mp[nums[i]] = i;
10         }
11         return false;
12     }
13 };
View Code

 


242. Valid Anagram (easy)

两个string的构成字母和个数是否相同

Given two strings s and t , write a function to determine if t is an anagram of s.

Example 1:

Input: s = "anagram", t = "nagaram"
Output: true
Example 2:

Input: s = "rat", t = "car"
Output: false
Note:
You may assume the string contains only lowercase alphabets.

Follow up:
What if the inputs contain unicode characters? How would you adapt your solution to such case?
problem
 1 class Solution {
 2 public:
 3     bool isAnagram(string s, string t) {
 4         vector<int> counter(26);
 5         for (auto a : s)
 6             ++counter[a - 'a'];
 7         for (auto b : t)
 8             --counter[b - 'a'];
 9         for (auto count : counter)
10             if (count != 0) return false;
11         return true;
12     }
13 };
View Code

 


274. H-Index (medium) #

h因子:高引用次数。返回一个最大的n,使有n个数的数值大于等于n

Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index.

According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at least h citations each, and the other N − h papers have no more than h citations each."

Example:

Input: citations = [3,0,6,1,5]
Output: 3 
Explanation: [3,0,6,1,5] means the researcher has 5 papers in total and each of them had 
             received 3, 0, 6, 1, 5 citations respectively. 
             Since the researcher has 3 papers with at least 3 citations each and the remaining 
             two with no more than 3 citations each, his h-index is 3.
Note: If there are several possible values for h, the maximum one is taken as the h-index.
problem
 1 class Solution {
 2 public:
 3     int hIndex(vector<int>& citations) {
 4         int length = citations.size();
 5         vector<int> counter(length + 1);
 6         for (int i = 0; i < length; ++i) {
 7             if (citations[i] >= length)
 8                 counter[length]++;
 9             else
10                 counter[citations[i]]++;
11         }
12         int sum = 0;
13         for (int j = length; j >= 0; --j) {
14             sum += counter[j];
15             if (sum >= j) return j;
16         }
17     }
18 };
View Code

 


290. Word Pattern (easy)

模板和词组是否匹配

Given a pattern and a string str, find if str follows the same pattern.

Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.

Example 1:

Input: pattern = "abba", str = "dog cat cat dog"
Output: true
Example 2:

Input:pattern = "abba", str = "dog cat cat fish"
Output: false
Example 3:

Input: pattern = "aaaa", str = "dog cat cat dog"
Output: false
Example 4:

Input: pattern = "abba", str = "dog dog dog dog"
Output: false
Notes:
You may assume pattern contains only lowercase letters, and str contains lowercase letters separated by a single space.
problem
 1 class Solution {
 2 public:
 3     bool wordPattern(string pattern, string str) {
 4         vector<int> pmap(256, 0);
 5         unordered_map<string, int> smap;
 6         istringstream in(str);
 7         int i = 0, len = pattern.size();
 8         for (string word; in >> word; ++i) {
 9             if (pmap[pattern[i]] != smap[word])
10                 return false;
11             pmap[pattern[i]] = smap[word] = i + 1;
12         }
13         return i == len;
14     }
15 };
View Code

 


299. Bulls and Cows (medium)

两个string完全匹配位的个数和相同但不同位的个数

You are playing the following Bulls and Cows game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called "bulls") and how many digits match the secret number but locate in the wrong position (called "cows"). Your friend will use successive guesses and hints to eventually derive the secret number.

Write a function to return a hint according to the secret number and friend's guess, use A to indicate the bulls and B to indicate the cows. 

Please note that both secret number and friend's guess may contain duplicate digits.

Example 1:

Input: secret = "1807", guess = "7810"

Output: "1A3B"

Explanation: 1 bull and 3 cows. The bull is 8, the cows are 0, 1 and 7.
Example 2:

Input: secret = "1123", guess = "0111"

Output: "1A1B"

Explanation: The 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow.
Note: You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal.
problem
 1 class Solution {
 2 public:
 3     string getHint(string secret, string guess) {
 4         int cows = 0, bulls = 0;
 5         vector<char> map(10, 0);
 6         for (int i = 0; i < secret.size(); ++i) {
 7             if (secret[i] == guess[i])
 8                 ++bulls;
 9             else {
10                 if (map[secret[i] - '0'] < 0) cows++;
11                 if (map[guess[i] - '0'] > 0) cows++;
12                 map[secret[i] - '0']++;
13                 map[guess[i] - '0']--;
14             }
15         }
16         return to_string(bulls) + 'A' + to_string(cows) + 'B';
17     }
18 };
View Code

 


336. Palindrome Pairs (hard) #

选出能构成回文的string组合(两个string一组)。

Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.

Example 1:
Given words = ["bat", "tab", "cat"]
Return [[0, 1], [1, 0]]
The palindromes are ["battab", "tabbat"]
Example 2:
Given words = ["abcd", "dcba", "lls", "s", "sssll"]
Return [[0, 1], [1, 0], [3, 2], [2, 4]]
The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"]
problem
 1 // 把所有string存到map中,然后遍历每个string,把string拆成两半,一半是回文,另一半的反转在map中,则满足。
 2 // 拆分时包括空串+string,不包括string+空串,以防重复。
 3 // 如果有空串,则回文的两边都可加空串,但拆分过程忽略了左边加空串的情况,所以单独考虑。
 4 class Solution {
 5 public:
 6     vector<vector<int>> palindromePairs(vector<string>& words) {
 7         unordered_map<string, int> mp;
 8         vector<vector<int>> res;
 9         for (int i = 0; i < words.size(); ++i) {
10             string rev = words[i];
11             reverse(rev.begin(), rev.end());
12             mp[rev] = i;
13         }
14         if (mp.find("") != mp.end()) {
15             for (int i = 0; i < words.size(); ++i)
16                 if (words[i] != "" && isPalindrome(words[i]))
17                     res.push_back({mp[""], i});
18         }
19         for (int i = 0; i < words.size(); ++i) {
20             for (int j = 0; j < words[i].size(); ++j) {
21                 string left = words[i].substr(0, j);
22                 string right = words[i].substr(j);
23                 if (mp.find(right) != mp.end() && isPalindrome(left) && mp[right] != i)
24                     res.push_back({mp[right], i});
25                 if (mp.find(left) != mp.end() && isPalindrome(right) && mp[left] != i)
26                     res.push_back({i, mp[left]});
27             }
28         }
29         return res;
30     }
31     bool isPalindrome(string s) {
32         int left = 0, right = s.size() - 1;
33         while (left < right) {
34             if (s[left++] != s[right--])
35                 return false;
36         }
37         return true;
38     }
39 };
View Code

 


347. Top K Frequent Elements (medium) #

出现次数最高的k个数

Given a non-empty array of integers, return the k most frequent elements.

For example,
Given [1,1,1,2,2,3] and k = 2, return [1,2].

Note: 
You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
problem
 1 // 用map计数,然后用桶排序或最大堆对计数排序,找出最大的k个。
 2 class Solution {
 3 public:
 4     vector<int> topKFrequent(vector<int>& nums, int k) {
 5         vector<int> res;
 6         unordered_map<int, int> map;
 7         vector<vector<int>> freq(nums.size(), vector<int>());
 8         for (auto n : nums)
 9             map[n]++;
10         for (auto m : map)
11             freq[m.second - 1].push_back(m.first);
12         for (int i = freq.size() - 1; k > 0; --i) {
13             if (freq[i].size() != 0) {
14                 for (auto n : freq[i]) {
15                     res.push_back(n);
16                     --k;
17                 }
18             }
19         }
20         return res;
21     }
22 };
View Code

 


349. Intersection of Two Arrays (easy)

找到两个数组的交集,返回数组不含重复数字

Given two arrays, write a function to compute their intersection.

Example:
Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2].

Note:
Each element in the result must be unique.
The result can be in any order.
problem
 1 class Solution {
 2 public:
 3     vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
 4         unordered_set<int> numSet(nums1.begin(), nums1.end());
 5         vector<int> res;
 6         for (auto num2 : nums2) {
 7             if (numSet.count(num2)) {
 8                 res.push_back(num2);
 9                 numSet.erase(num2);
10             }
11         }
12         return res;
13     }
14 };
View Code

 


350. Intersection of Two Arrays II (easy)

找到两个数组的交集,返回数组含重复数字

Given two arrays, write a function to compute their intersection.

Example:
Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2].

Note:
Each element in the result should appear as many times as it shows in both arrays.
The result can be in any order.
Follow up:
What if the given array is already sorted? How would you optimize your algorithm?
What if nums1's size is small compared to nums2's size? Which algorithm is better?
What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?
problem
 1 class Solution {
 2 public:
 3     vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
 4         unordered_map<int, int> numMap;
 5         for (auto num1 : nums1)
 6             numMap[num1]++;
 7         vector<int> res;
 8         for (auto num2 : nums2) {
 9             if (numMap[num2] > 0) {
10                 res.push_back(num2);
11                 --numMap[num2];
12             }
13         }
14         return res;
15     }
16 };
View Code

 


355. Design Twitter (medium) #     待做

设计twitter

Design a simplified version of Twitter where users can post tweets, follow/unfollow another user and is able to see the 10 most recent tweets in the user's news feed. Your design should support the following methods:

postTweet(userId, tweetId): Compose a new tweet.
getNewsFeed(userId): Retrieve the 10 most recent tweet ids in the user's news feed. Each item in the news feed must be posted by users who the user followed or by the user herself. Tweets must be ordered from most recent to least recent.
follow(followerId, followeeId): Follower follows a followee.
unfollow(followerId, followeeId): Follower unfollows a followee.
Example:

Twitter twitter = new Twitter();

// User 1 posts a new tweet (id = 5).
twitter.postTweet(1, 5);

// User 1's news feed should return a list with 1 tweet id -> [5].
twitter.getNewsFeed(1);

// User 1 follows user 2.
twitter.follow(1, 2);

// User 2 posts a new tweet (id = 6).
twitter.postTweet(2, 6);

// User 1's news feed should return a list with 2 tweet ids -> [6, 5].
// Tweet id 6 should precede tweet id 5 because it is posted after tweet id 5.
twitter.getNewsFeed(1);

// User 1 unfollows user 2.
twitter.unfollow(1, 2);

// User 1's news feed should return a list with 1 tweet id -> [5],
// since user 1 is no longer following user 2.
twitter.getNewsFeed(1);
problem
 1 // 参考代码
 2 class Twitter
 3 {
 4     struct Tweet
 5     {
 6         int time;
 7         int id;
 8         Tweet(int time, int id) : time(time), id(id) {}
 9     };
10 
11     std::unordered_map<int, std::vector<Tweet>> tweets; // [u] = array of tweets by u
12     std::unordered_map<int, std::unordered_set<int>> following; // [u] = array of users followed by u
13 
14     int time;
15 
16 public:
17     Twitter() : time(0) {}
18 
19     void postTweet(int userId, int tweetId)
20     {
21         tweets[userId].emplace_back(time++, tweetId);
22     }
23 
24     std::vector<int> getNewsFeed(int userId)
25     {
26         std::vector<std::pair<Tweet*, Tweet*>> h; // pair of pointers (begin, current)
27 
28         for (auto& u: following[userId])
29         {
30             auto& t = tweets[u];
31             if (t.size() > 0)
32                 h.emplace_back(t.data(), t.data() + t.size() - 1);
33         }
34         auto& t = tweets[userId]; // self
35         if (t.size() > 0)
36             h.emplace_back(t.data(), t.data() + t.size() - 1);
37 
38         auto f = [](const std::pair<Tweet*, Tweet*>& x, const std::pair<Tweet*, Tweet*>& y) {
39             return x.second->time < y.second->time;
40         };
41         std::make_heap(h.begin(), h.end(), f);
42 
43         const int n = 10;
44         std::vector<int> o;
45         o.reserve(n);
46         for (int i = 0; (i < n) && !h.empty(); ++i)
47         {
48             std::pop_heap(h.begin(), h.end(), f);
49 
50             auto& hb = h.back();
51             o.push_back(hb.second->id);
52 
53             if (hb.first == hb.second--)
54                 h.pop_back();
55             else
56                 std::push_heap(h.begin(), h.end(), f);
57         }
58         return o;
59     }
60 
61     void follow(int followerId, int followeeId)
62     {
63         if (followerId != followeeId)
64             following[followerId].insert(followeeId);
65     }
66 
67     void unfollow(int followerId, int followeeId)
68     {
69         following[followerId].erase(followeeId);
70     }
71 };
View Code

 


380. Insert Delete GetRandom O(1) (medium)

插入和删除数据,随机取数据。

Design a data structure that supports all following operations in average O(1) time.

insert(val): Inserts an item val to the set if not already present.
remove(val): Removes an item val from the set if present.
getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.
Example:

// Init an empty set.
RandomizedSet randomSet = new RandomizedSet();

// Inserts 1 to the set. Returns true as 1 was inserted successfully.
randomSet.insert(1);

// Returns false as 2 does not exist in the set.
randomSet.remove(2);

// Inserts 2 to the set, returns true. Set now contains [1,2].
randomSet.insert(2);

// getRandom should return either 1 or 2 randomly.
randomSet.getRandom();

// Removes 1 from the set, returns true. Set now contains [2].
randomSet.remove(1);

// 2 was already in the set, so return false.
randomSet.insert(2);

// Since 2 is the only number in the set, getRandom always return 2.
randomSet.getRandom();
problem
 1 class RandomizedSet {
 2 public:
 3     /** Initialize your data structure here. */
 4     RandomizedSet() {
 5         
 6     }
 7     
 8     /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
 9     bool insert(int val) {
10         if (index.find(val) != index.end())
11             return false;
12         index[val] = randomSet.size();
13         randomSet.push_back(val);
14         return true;
15     }
16     
17     /** Removes a value from the set. Returns true if the set contained the specified element. */
18     bool remove(int val) {
19         if (index.find(val) == index.end())
20             return false;
21         randomSet[index[val]] = randomSet.back();
22         index[randomSet.back()] = index[val];
23         randomSet.pop_back();
24         index.erase(val);
25         return true;
26     }
27     
28     /** Get a random element from the set. */
29     int getRandom() {
30         return randomSet[rand()%randomSet.size()];
31     }
32 private:
33     vector<int> randomSet;
34     unordered_map<int, int> index;
35 };
36 
37 /**
38  * Your RandomizedSet object will be instantiated and called as such:
39  * RandomizedSet obj = new RandomizedSet();
40  * bool param_1 = obj.insert(val);
41  * bool param_2 = obj.remove(val);
42  * int param_3 = obj.getRandom();
43  */
View Code

 


381. Insert Delete GetRandom O(1) - Duplicates allowed (hard)

插入和删除数据,随机取数据。数据有重复。

Design a data structure that supports all following operations in average O(1) time.

Note: Duplicate elements are allowed.
insert(val): Inserts an item val to the collection.
remove(val): Removes an item val from the collection if present.
getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.
Example:

// Init an empty collection.
RandomizedCollection collection = new RandomizedCollection();

// Inserts 1 to the collection. Returns true as the collection did not contain 1.
collection.insert(1);

// Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1].
collection.insert(1);

// Inserts 2 to the collection, returns true. Collection now contains [1,1,2].
collection.insert(2);

// getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3.
collection.getRandom();

// Removes 1 from the collection, returns true. Collection now contains [1,2].
collection.remove(1);

// getRandom should return 1 and 2 both equally likely.
collection.getRandom();
problem
 1 class RandomizedCollection {
 2 public:
 3     /** Initialize your data structure here. */
 4     RandomizedCollection() {
 5         
 6     }
 7     
 8     /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
 9     bool insert(int val) {
10         bool res = index.find(val) == index.end();
11         index[val].push_back(nums.size());
12         nums.push_back({val, index[val].size() - 1});
13         return res;
14     }
15     
16     /** Removes a value from the collection. Returns true if the collection contained the specified element. */
17     bool remove(int val) {
18         if (index.find(val) == index.end())
19             return false;
20         index[nums.back().first][nums.back().second] = index[val].back();
21         nums[index[val].back()] = nums.back();
22         index[val].pop_back();
23         nums.pop_back();
24         if (index[val].empty())
25             index.erase(val);
26         return true;
27     }
28     
29     /** Get a random element from the collection. */
30     int getRandom() {
31         return nums[rand()%nums.size()].first;
32     }
33 private:
34     vector<pair<int, int>> nums;
35     unordered_map<int, vector<int>> index;
36 };
37 
38 /**
39  * Your RandomizedCollection object will be instantiated and called as such:
40  * RandomizedCollection obj = new RandomizedCollection();
41  * bool param_1 = obj.insert(val);
42  * bool param_2 = obj.remove(val);
43  * int param_3 = obj.getRandom();
44  */
View Code

 


387. First Unique Character in a String (easy)

找到第一个非重复的字母

Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1.

Examples:

s = "leetcode"
return 0.

s = "loveleetcode",
return 2.
Note: You may assume the string contain only lowercase letters.
problem
 1 class Solution {
 2 public:
 3     int firstUniqChar(string s) {
 4         int frq[26] = {0};
 5         for (auto c : s)
 6             ++frq[c - 'a'];
 7         for (int i = 0; i < s.size(); ++i) {
 8             if (frq[s[i] - 'a'] == 1)
 9                 return i;
10         }
11         return -1;
12     }
13 };
View Code

 


389. Find the Difference (easy)

找到一个string比另一个多出来的字母

Given two strings s and t which consist of only lowercase letters.

String t is generated by random shuffling string s and then add one more letter at a random position.

Find the letter that was added in t.

Example:

Input:
s = "abcd"
t = "abcde"

Output:
e

Explanation:
'e' is the letter that was added.
problem
 1 class Solution {
 2 public:
 3     char findTheDifference(string s, string t) {
 4         char res = 0;
 5         for (auto c : s)
 6             res ^= c;
 7         for (auto c : t)
 8             res ^= c;
 9         return res;
10     }
11 };
View Code

 


409. Longest Palindrome (easy)

一些字母可以组成的最长回文

Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.

This is case sensitive, for example "Aa" is not considered a palindrome here.

Note:
Assume the length of given string will not exceed 1,010.

Example:

Input:
"abccccdd"

Output:
7

Explanation:
One longest palindrome that can be built is "dccaccd", whose length is 7.
problem
 1 class Solution {
 2 public:
 3     int longestPalindrome(string s) {
 4         vector<int> map(256, 0);
 5         int res = 0;
 6         for (auto c : s)
 7             map[c]++;
 8         for (auto m : map)
 9             res += m - (m&1);
10         return res == s.size() ? res : res + 1;
11     }
12 };
View Code

 


438. Find All Anagrams in a String (easy)

在s中查找p的乱序字符串。

Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.

Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.

The order of output does not matter.

Example 1:

Input:
s: "cbaebabacd" p: "abc"

Output:
[0, 6]

Explanation:
The substring with start index = 0 is "cba", which is an anagram of "abc".
The substring with start index = 6 is "bac", which is an anagram of "abc".
Example 2:

Input:
s: "abab" p: "ab"

Output:
[0, 1, 2]

Explanation:
The substring with start index = 0 is "ab", which is an anagram of "ab".
The substring with start index = 1 is "ba", which is an anagram of "ab".
The substring with start index = 2 is "ab", which is an anagram of "ab".
problem
 1 // slide window cnt不需要记录所有差异个数,只需记录p中有的字母的差异数。
 2 class Solution {
 3 public:
 4     vector<int> findAnagrams(string s, string p) {
 5         vector<int> res;
 6         int cnt = p.size(), pSize = p.size();
 7         vector<int> mp(256);
 8         for (char c : p)
 9             ++mp[c];
10         for (int i = 0; i < s.size(); ++i) {
11             if (mp[s[i]]-- > 0)
12                 --cnt;
13             if (i >= pSize && mp[s[i - pSize]]++ >= 0)
14                 ++cnt;
15             if (cnt == 0)
16                 res.push_back(i + 1 - pSize);
17         }
18         return res;
19     }
20 };
View Code

 


447. Number of Boomerangs (easy) #

相等长度线段组合数量

Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters).

Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive).

Example:
Input:
[[0,0],[1,0],[2,0]]

Output:
2

Explanation:
The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]]
problem
 1 class Solution {
 2 public:
 3     int numberOfBoomerangs(vector<pair<int, int>>& points) {
 4         int res = 0;
 5         for (int i = 0; i < points.size(); ++i) {
 6             unordered_map<int, int> map;
 7             for (int j = 0; j < points.size(); ++j) {
 8                 if (i == j) continue;
 9                 int dx = points[i].first - points[j].first;
10                 int dy = points[i].second - points[j].second;
11                 int dis = dx*dx + dy*dy;
12                 map[dis]++;
13             }
14             for (auto m : map)
15                 if (m.second) res += m.second*(m.second - 1);
16         }
17         return res;
18     }
19 };
View Code

 


451. Sort Characters By Frequency (medium) #

以字母出现频率排序字符串

Given a string, sort it in decreasing order based on the frequency of characters.

Example 1:

Input:
"tree"

Output:
"eert"

Explanation:
'e' appears twice while 'r' and 't' both appear once.
So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid answer.
Example 2:

Input:
"cccaaa"

Output:
"cccaaa"

Explanation:
Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer.
Note that "cacaca" is incorrect, as the same characters must be together.
Example 3:

Input:
"Aabb"

Output:
"bbAa"

Explanation:
"bbaA" is also a valid answer, but "Aabb" is incorrect.
Note that 'A' and 'a' are treated as two different characters.
problem
 1 // 捕获引用,隐式捕获用到的变量
 2 class Solution {
 3 public:
 4     string frequencySort(string s) {
 5         vector<int> map(256, 0);
 6         for (auto c : s) map[c]++;
 7         sort(s.begin(), s.end(), [&](char m, char n) {
 8             return map[m] > map[n] || (map[m] == map[n] && m < n);
 9         });
10         return s;
11     }
12 };
View Code

 


454. 4Sum II (medium)

4各数组,各取一个数,和为0的组合个数

Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero.

To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1.

Example:

Input:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]

Output:
2

Explanation:
The two tuples are:
1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
problem
 1 class Solution {
 2 public:
 3     int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
 4         unordered_map<int, int> map;
 5         int res = 0;
 6         for (auto a : A) {
 7             for (auto b : B) {
 8                 map[a + b]++;
 9             }
10         }
11         for (auto c : C) {
12             for (auto d : D) {
13                 res += map[-(c + d)];
14             }
15         }
16         return res;
17     }
18 };
View Code

 


463. Island Perimeter (easy)

计算岛屿的周长

You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn't have "lakes" (water inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island.

Example:

[[0,1,0,0],
 [1,1,1,0],
 [0,1,0,0],
 [1,1,0,0]]

Answer: 16
Explanation: The perimeter is the 16 yellow stripes in the image below:
problem
 1 class Solution {
 2 public:
 3     int islandPerimeter(vector<vector<int>>& grid) {
 4         int m = grid.size(), n = grid[0].size();
 5         int cells = 0, sides = 0;
 6         for (int i = 0; i < m; ++i) {
 7             for (int j = 0; j < n; ++j) {
 8                 if (grid[i][j]) {
 9                     cells++;
10                     if (i > 0 && grid[i - 1][j]) sides++;
11                     if (i < m - 1 && grid[i + 1][j]) sides++;
12                     if (j > 0 && grid[i][j - 1]) sides++;
13                     if (j < n - 1 && grid[i][j + 1]) sides++;
14                 }
15             }
16         }
17         return cells*4 - sides;
18     }
19 };
View Code

 


500. Keyboard Row (easy)

能用键盘上一行按键打出来的string

Given a List of words, return the words that can be typed using letters of alphabet on only one row's of American keyboard like the image below.

American keyboard

Example 1:
Input: ["Hello", "Alaska", "Dad", "Peace"]
Output: ["Alaska", "Dad"]
Note:
You may use one character in the keyboard more than once.
You may assume the input string will only contain letters of alphabet.
problem
 1 class Solution {
 2 public:
 3     vector<string> findWords(vector<string>& words) {
 4         vector<string> res;
 5         vector<int> map(256, 0);
 6         for (auto c : "qwertyuiopQWERTYUIOP") map[c] = 1;
 7         for (auto c : "asdfghjklASDFGHJKL") map[c] = 2;
 8         for (auto c : "zxcvbnmZXCVBNM") map[c] = 3;
 9         for (auto s : words) {
10             int i = map[s[0]];
11             for (auto c : s)
12                 if (map[c] != i) {i = 4; break;}
13             if (i != 4) res.push_back(s);
14         }
15         return res;
16     }
17 };
View Code

 


508. Most Frequent Subtree Sum (medium)

计算各节点的子节点的和,出现次数最多sum值

Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order.

Examples 1
Input:

  5
 /  \
2   -3
return [2, -3, 4], since all the values happen only once, return all of them in any order.
Examples 2
Input:

  5
 /  \
2   -5
return [2], since 2 happens twice, however -5 only occur once.
Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer.
problem
 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     vector<int> findFrequentTreeSum(TreeNode* root) {
13         unordered_map<int, int> mp;
14         vector<int> res;
15         int maxVal = 0;
16         help(root, mp, maxVal);
17         for (auto m : mp) {
18             if (m.second == maxVal)
19                 res.push_back(m.first);
20         }
21         return res;
22     }
23     int help(TreeNode* node, unordered_map<int, int>& mp, int& maxVal) {
24         if (!node)
25             return 0;
26         int sum = node->val + help(node->left, mp, maxVal) + help(node->right, mp, maxVal);
27         maxVal = max(maxVal, ++mp[sum]);
28         return sum;
29     }
30 };
View Code

 


525. Contiguous Array (medium)

0和1个数一样的最长子数组

Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1.

Example 1:
Input: [0,1]
Output: 2
Explanation: [0, 1] is the longest contiguous subarray with equal number of 0 and 1.
Example 2:
Input: [0,1,0]
Output: 2
Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1.
Note: The length of the given binary array will not exceed 50,000.
problem
 1 class Solution {
 2 public:
 3     int findMaxLength(vector<int>& nums) {
 4         int res = 0, sum = 0;
 5         unordered_map<int, int> map;
 6         for (auto& n : nums) if (n == 0) n = -1;
 7         for (int i = 0; i < nums.size(); ++i) {
 8             sum += nums[i];
 9             if (sum == 0) res = max(res, i + 1);
10             else if (map[sum] == 0) map[sum] = i + 1;
11             else res = max(res, i + 1 - map[sum]);
12         }
13         return res;
14     }
15 };
View Code

 


535. Encode and Decode TinyURL (medium) #

设计短网址转换系统

Note: This is a companion problem to the System Design problem: Design TinyURL.
TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as http://tinyurl.com/4e9iAk.

Design the encode and decode methods for the TinyURL service. There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL.
problem
 1 class Solution {
 2 public:
 3     string dict = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 4     int id = 0;
 5     unordered_map<string,string> m;  //key is longURL, value is shortURL
 6     unordered_map<int, string> idm;  //key is id in DB, value is longURL
 7     // Encodes a URL to a shortened URL.
 8     string encode(string longUrl) {
 9         if(m.find(longUrl) != m.end())return m[longUrl];
10         string res = "";
11         id++;
12         int count = id;
13         while(count > 0)
14         {
15             res = dict[count%62] + res;
16             count /= 62;
17         }
18         while(res.size() < 6)
19         {
20             res = "0" + res;
21         }
22         m[longUrl] = res;
23         idm[id] = longUrl;
24         return res;
25     }
26 
27     // Decodes a shortened URL to its original URL.
28     string decode(string shortUrl) {
29         int id = 0;
30         for(int i = 0; i < shortUrl.size(); i++)
31         {
32             id = 62*id + (int)(dict.find(shortUrl[i]));
33         }
34         if(idm.find(id) != idm.end())return idm[id];
35         return "";
36     }
37 };
View Code

 


554. Brick Wall (medium)

画条竖线,经过最少的砖

There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The bricks have the same height but different width. You want to draw a vertical line from the top to the bottom and cross the least bricks.

The brick wall is represented by a list of rows. Each row is a list of integers representing the width of each brick in this row from left to right.

If your line go through the edge of a brick, then the brick is not considered as crossed. You need to find out how to draw the line to cross the least bricks and return the number of crossed bricks.

You cannot draw a line just along one of the two vertical edges of the wall, in which case the line will obviously cross no bricks.

Example:
Input: 
[[1,2,2,1],
 [3,1,2],
 [1,3,2],
 [2,4],
 [3,1,2],
 [1,3,1,1]]
Output: 2
Explanation: 

Note:
The width sum of bricks in different rows are the same and won't exceed INT_MAX.
The number of bricks in each row is in range [1,10,000]. The height of wall is in range [1,10,000]. Total number of bricks of the wall won't exceed 20,000.
problem
 1 class Solution {
 2 public:
 3     int leastBricks(vector<vector<int>>& wall) {
 4         int res = 0;
 5         unordered_map<int, int> map;
 6         for (auto w : wall) {
 7             int sum = 0;
 8             for (int i = 0; i < w.size() - 1; ++i)
 9                 res = max(res, ++map[sum += w[i]]);
10         }
11         return wall.size() - res;
12     }
13 };
View Code

 


560. Subarray Sum Equals K (medium)

和为k的连续子数组个数

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.

Example 1:
Input:nums = [1,1,1], k = 2
Output: 2
Note:
The length of the array is in range [1, 20,000].
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].
problem
 1 class Solution {
 2 public:
 3     int subarraySum(vector<int>& nums, int k) {
 4         int count = 0, sum = 0;
 5         unordered_map<int, int> map;
 6         map[0] = 1;
 7         for (int n : nums) {
 8             sum += n;
 9             if (map.find(sum - k) != map.end())
10                 count += map[sum - k];        // 不能是1,因为数组中可能有0
11             ++map[sum];
12         }
13         return count;
14     }
15 };
View Code

 


575. Distribute Candies (easy) #

把糖平均分为两份,其中一个人可得到的最多种类

Given an integer array with even length, where different numbers in this array represent different kinds of candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain.
Example 1:
Input: candies = [1,1,2,2,3,3]
Output: 3
Explanation:
There are three different kinds of candies (1, 2 and 3), and two candies for each kind.
Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too. 
The sister has three different kinds of candies. 
Example 2:
Input: candies = [1,1,2,3]
Output: 2
Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1]. 
The sister has two different kinds of candies, the brother has only one kind of candies. 
Note:

The length of the given array is in range [2, 10,000], and will be even.
The number in given array is in range [-100,000, 100,000].
problem
class Solution {
public:
    int distributeCandies(vector<int>& candies) {
        bitset<200001> set;
        int count = 0;
        for (auto c : candies) {
            if (!set.test(c + 100000)) {
                count++;
                set.set(c + 100000);
            }
        }
        return count > candies.size()/2 ? candies.size()/2 : count;
    }
};
View Code

 


594. Longest Harmonious Subsequence (easy)

元素相差最多为1的子数组最大大小

We define a harmonious array is an array where the difference between its maximum value and its minimum value is exactly 1.

Now, given an integer array, you need to find the length of its longest harmonious subsequence among all its possible subsequences.

Example 1:
Input: [1,3,2,2,5,2,3,7]
Output: 5
Explanation: The longest harmonious subsequence is [3,2,2,2,3].
Note: The length of the input array will not exceed 20,000.
problem
 1 class Solution {
 2 public:
 3     int findLHS(vector<int>& nums) {
 4         map<int, int> map;
 5         int last_num = 0, last_count = 0, res = 0;
 6         for (auto n : nums)
 7             map[n]++;
 8         for (auto pair : map) {
 9             if (last_count && pair.first - last_num == 1)
10                 res = max(res, pair.second + last_count);
11             last_num = pair.first;
12             last_count = pair.second;
13         }
14         return res;
15     }
16 };
View Code

 


609. Find Duplicate File in System (medium)

把内容相同的文件合并在一起

Given a list of directory info including directory path, and all the files with contents in this directory, you need to find out all the groups of duplicate files in the file system in terms of their paths.

A group of duplicate files consists of at least two files that have exactly the same content.

A single directory info string in the input list has the following format:

"root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)"

It means there are n files (f1.txt, f2.txt ... fn.txt with content f1_content, f2_content ... fn_content, respectively) in directory root/d1/d2/.../dm. Note that n >= 1 and m >= 0. If m = 0, it means the directory is just the root directory.

The output is a list of group of duplicate file paths. For each group, it contains all the file paths of the files that have the same content. A file path is a string that has the following format:

"directory_path/file_name.txt"

Example 1:
Input:
["root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d 4.txt(efgh)", "root 4.txt(efgh)"]
Output:  
[["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]]
Note:
No order is required for the final output.
You may assume the directory name, file name and file content only has letters and digits, and the length of file content is in the range of [1,50].
The number of files given is in the range of [1,20000].
You may assume no files or directories share the same name in the same directory.
You may assume each given directory info represents a unique directory. Directory path and file info are separated by a single blank space.
Follow-up beyond contest:
Imagine you are given a real file system, how will you search files? DFS or BFS?
If the file content is very large (GB level), how will you modify your solution?
If you can only read the file by 1kb each time, how will you modify your solution?
What is the time complexity of your modified solution? What is the most time-consuming part and memory consuming part of it? How to optimize?
How to make sure the duplicated files you find are not false positive?
problem
 1 class Solution {
 2 public:
 3     vector<vector<string>> findDuplicate(vector<string>& paths) {
 4         unordered_map<string, vector<string>> mp;
 5         for (string path : paths) {
 6             stringstream ss(path);
 7             string dir, s;
 8             getline(ss, dir, ' ');
 9             while (getline(ss, s, ' ')) {
10                 int left = s.find('('), right = s.find(')');
11                 string fileName = s.substr(0, left);
12                 string content = s.substr(left + 1, right - left - 1);
13                 mp[content].push_back(dir + "/" + fileName);
14             }
15         }
16         vector<vector<string>> res;
17         for (auto m : mp)
18             if (m.second.size() > 1)
19                 res.push_back(m.second);
20         return res;
21     }
22 };
View Code

 


632. Smallest Range (hard) #

至少覆盖每个数组中的一个数的最小区间

You have k lists of sorted integers in ascending order. Find the smallest range that includes at least one number from each of the k lists.

We define the range [a,b] is smaller than range [c,d] if b-a < d-c or a < c if b-a == d-c.

Example 1:
Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
Output: [20,24]
Explanation: 
List 1: [4, 10, 15, 24,26], 24 is in range [20,24].
List 2: [0, 9, 12, 20], 20 is in range [20,24].
List 3: [5, 18, 22, 30], 22 is in range [20,24].
Note:
The given list may contain duplicates, so ascending order means >= here.
1 <= k <= 3500
-105 <= value of elements <= 105.
For Java users, please note that the input type has been changed to List<List<Integer>>. And after you reset the code template, you'll see this point.
problem
 1 struct smaller {
 2     bool operator()(pair<int, int>& a, pair<int, int>& b) {
 3         return a.first > b.first;
 4     }
 5 };
 6 
 7 class Solution {
 8 public:
 9     vector<int> smallestRange(vector<vector<int>>& nums) {
10         int m = nums.size(), pqMax = INT_MIN;
11         priority_queue<pair<int, int>, vector<pair<int, int>>, smaller> pq;
12         vector<int> cnt(m, 1);
13         vector<int> index(m, 1);
14         for (int i = 0; i < m; ++i) {
15             pq.push({nums[i][0], i});
16             pqMax = max(pqMax, nums[i][0]);
17         }
18         vector<int> res = {pq.top().first, pqMax};
19         int size = res[1] - res[0];
20         while (1) {
21             int k = pq.top().second;
22             pq.pop();
23             if (index[k] == nums[k].size())
24                 return res;
25             pqMax = max(pqMax, nums[k][index[k]]);
26             pq.push({nums[k][index[k]++], k});
27             if (pqMax - pq.top().first < size) {
28                 size = pqMax - pq.top().first;
29                 res = {pq.top().first, pqMax};
30             }
31         }
32         return res;
33     }
34 };
View Code

 


632. Smallest Range (hard) #

 

 

 

 

 

 

 

 

 

#

转载于:https://www.cnblogs.com/fanshw/p/8882473.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值