LC128 Longest Consecutive Sequence
Problem
Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
Your algorithm should run in O(n) complexity.
Example:
1
2
3 Input: [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.
Think
首先将所有的num存进hash set,然后找到每一个连续序列的开头元素(即num - 1不存在的情况),向后判断每一个num + i是否存在,求得此处的最大长度。
Code
1 | int longestConsecutive(vector<int>& nums) { |
LC399 Evaluate Division
Problem
‘[[“a”,“c”],[“b”,“a”],[“a”,“e”],[“a”,“a”],[“x”,“x”]]’
Equations are given in the format
A / B = k
, whereA
andB
are variables represented as strings, andk
is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return-1.0
.Example:
Givena / b = 2.0, b / c = 3.0.
queries are:a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? .
return[6.0, 0.5, -1.0, 1.0, -1.0 ].
The input is:
vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries
, whereequations.size() == values.size()
, and the values are positive. This represents the equations. Returnvector<double>
.According to the example above:
1
2
3 equations = [ ["a", "b"], ["b", "c"] ],
values = [2.0, 3.0],
queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ].The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.
Think
并查集,首先实现两个函数,一个是getParent,用来获取某一个节点的最根部的父节点;另一个是unionNodes,用来合并两个节点,也就是将node1以及所有和node1共parent的节点合并到node2的分支上面,用对应的结果val进行连接。
对于每一个给出的公式,我们首先判断前后两个变量是否出现过:
- 如果都没有出现过,则均需要新建,node1作为被除数,设值为val,node2作为除数,设值为1,然后将node1连接到node2上;
- 如果被除数没出现过,除数出现过,则新建被除数,设置被除数的值为除数对应节点的值乘val;
- 如果被除数出现过,除数没出现过,则新建除数,设置除数的值为被除数除以val;
- 如果两者都出现过,则使用unionNodes将两个节点连起来。
对于每一个query,首先判断除数和被除数是否为已知变量,且具有相同的最根父节点(说明可以除),如果不满足条件返回-1,否则返回被除数的值除以除数的值。
Code
1 | struct Node { |
LC547 Friend Circles
Problem
There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a directfriend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.
Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.
Example 1:
1
2
3
4
5
6
7 Input:
[[1,1,0],
[1,1,0],
[0,0,1]]
Output: 2
Explanation:The 0th and 1st students are direct friends, so they are in a friend circle.
The 2nd student himself is in a friend circle. So return 2.Example 2:
1
2
3
4
5
6
7 Input:
[[1,1,0],
[1,1,1],
[0,1,1]]
Output: 1
Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends,
so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.Note:
- N is in range [1,200].
- M[i][i] = 1 for all students.
- If M[i][j] = 1, then M[j][i] = 1.
Think
并查集。主要实现两个部分,一是getRoot,二是对于两个节点应当如何合并。
Code
1 | int getRoot(vector<int> &root, int i){ |
LC684 Redundant Connection
Problem
In this problem, a tree is an undirected graph that is connected and has no cycles.
The given input is a graph that started as a tree with N nodes (with distinct values 1, 2, …, N), with one additional edge added. The added edge has two different vertices chosen from 1 to N, and was not an edge that already existed.
The resulting graph is given as a 2D-array of
edges
. Each element ofedges
is a pair[u, v]
withu < v
, that represents an undirected edge connecting nodesu
andv
.Return an edge that can be removed so that the resulting graph is a tree of N nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array. The answer edge
[u, v]
should be in the same format, withu < v
.Example 1:
1
2
3
4
5
6 Input: [[1,2], [1,3], [2,3]]
Output: [2,3]
Explanation: The given undirected graph will be like this:
1
/ \
2 - 3Example 2:
1
2
3
4
5
6 Input: [[1,2], [2,3], [3,4], [1,4], [1,5]]
Output: [1,4]
Explanation: The given undirected graph will be like this:
5 - 1 - 2
| |
4 - 3Note:
The size of the input 2D-array will be between 3 and 1000.
Every integer represented in the 2D-array will be between 1 and N, where N is the size of the input array.
Think
并查集,主要实现的就是并查集的两个函数。
Code
1 | vector<int> findRedundantConnection(vector<vector<int>>& edges) { |
LC685 Redundant Connection II
Problem
In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) for which all other nodes are descendants of this node, plus every node has exactly one parent, except for the root node which has no parents.
The given input is a directed graph that started as a rooted tree with N nodes (with distinct values 1, 2, …, N), with one additional directed edge added. The added edge has two different vertices chosen from 1 to N, and was not an edge that already existed.
The resulting graph is given as a 2D-array of
edges
. Each element ofedges
is a pair[u, v]
that represents a directed edge connecting nodesu
andv
, whereu
is a parent of childv
.Return an edge that can be removed so that the resulting graph is a rooted tree of N nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array.
Example 1:
1
2
3
4
5
6
7 Input: [[1,2], [1,3], [2,3]]
Output: [2,3]
Explanation: The given directed graph will be like this:
1
/ \
v v
2-->3Example 2:
1
2
3
4
5
6
7 Input: [[1,2], [2,3], [3,4], [4,1], [1,5]]
Output: [4,1]
Explanation: The given directed graph will be like this:
5 <- 1 -> 2
^ |
| v
4 <- 3Note:
The size of the input 2D-array will be between 3 and 1000.
Every integer represented in the 2D-array will be between 1 and N, where N is the size of the input array.
Think
getRoot函数和上题类似。
主要分三种情况:
- 无环,但是有入度为2的节点,返回的是后加入的那一条边
- 有环,且没有入度为2的节点,返回的是最后组成环的那一条边
- 有环,且有入度为2的节点,返回的是组成环,且是加入入度为2的边的后一条边
因此需要用first和second来记录前后遍历到的两条边,如果当前边对应有root,则说明之前已经有入度为1了,所以需要记录first和second,然后将edge的出节点置为-1.
Code
1 | vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) { |
LC721 Accounts Merge
Problem
Given a list
accounts
, each elementaccounts[i]
is a list of strings, where the first elementaccounts[i][0]
is a name, and the rest of the elements are emails representing emails of the account.Now, we would like to merge these accounts. Two accounts definitely belong to the same person if there is some email that is common to both accounts. Note that even if two accounts have the same name, they may belong to different people as people could have the same name. A person can have any number of accounts initially, but all of their accounts definitely have the same name.
After merging the accounts, return the accounts in the following format: the first element of each account is the name, and the rest of the elements are emails in sorted order. The accounts themselves can be returned in any order.
Example 1:
1
2
3
4
5
6
7
8 Input:
accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], ["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]]
Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]]
Explanation:
The first and third John's are the same person as they have the common email "johnsmith@mail.com".
The second John and Mary are different people as none of their email addresses are used by other accounts.
We could return these lists in any order, for example the answer [['Mary', 'mary@mail.com'], ['John', 'johnnybravo@mail.com'],
['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted.Note:
The length of
accounts
will be in the range[1, 1000]
.The length of
accounts[i]
will be in the range[1, 10]
.The length of
accounts[i][j]
will be in the range[1, 30]
.
Think
并查集,首先建立hash map存放root,建立hash map存放每个email对应的name,建立hash表存放所有email对应的序列结果。
首先遍历accounts,构建root和owner数组;
然后遍历accounts,将每一个email连接到对应的root的根节点上;
然后遍历account,将相同root的email存在hash map的相同区域的set里面;
最后将结果的hash map转化成二维数组。
Code
1 | vector<vector<string>> accountsMerge(vector<vector<string>>& accounts) { |
LC794 Valid Tic-Tac-Toe State
Problem
A Tic-Tac-Toe board is given as a string array
board
. Return True if and only if it is possible to reach this board position during the course of a valid tic-tac-toe game.The
board
is a 3 x 3 array, and consists of characters" "
,"X"
, and"O"
. The " " character represents an empty square.Here are the rules of Tic-Tac-Toe:
- Players take turns placing characters into empty squares (" ").
- The first player always places “X” characters, while the second player always places “O” characters.
- “X” and “O” characters are always placed into empty squares, never filled ones.
- The game ends when there are 3 of the same (non-empty) character filling any row, column, or diagonal.
- The game also ends if all squares are non-empty.
- No more moves can be played if the game is over.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 Example 1:
Input: board = ["O ", " ", " "]
Output: false
Explanation: The first player always plays "X".
Example 2:
Input: board = ["XOX", " X ", " "]
Output: false
Explanation: Players take turns making moves.
Example 3:
Input: board = ["XXX", " ", "OOO"]
Output: false
Example 4:
Input: board = ["XOX", "O O", "XOX"]
Output: trueNote:
board
is a length-3 array of strings, where each stringboard[i]
has length 3.- Each
board[i][j]
is a character in the set{" ", "X", "O"}
.
Think
直接检查即可。
Code
1 | bool validTicTacToe(vector<string>& board) { |
LC821 Shortest Distance to a Character
Problem
Given a string
S
and a characterC
, return an array of integers representing the shortest distance from the characterC
in the string.Example 1:
1
2 Input: S = "loveleetcode", C = 'e'
Output: [3, 2, 1, 0, 1, 0, 0, 1, 2, 2, 1, 0]Note:
S
string length is in[1, 10000].
C
is a single character, and guaranteed to be in stringS
.- All letters in
S
andC
are lowercase.
Think
遍历两次数组,分别从前往后和从后往前,记录字符C的位置,然后取i - pos 或者 pos - i即可。
Code
1 | vector<int> shortestToChar(string S, char C) { |
LC869 Reordered Power of 2
Problem
Starting with a positive integer
N
, we reorder the digits in any order (including the original order) such that the leading digit is not zero.Return
true
if and only if we can do this in a way such that the resulting number is a power of 2.Example 1:
1
2 Input: 1
Output: trueExample 2:
1
2 Input: 10
Output: falseExample 3:
1
2 Input: 16
Output: trueExample 4:
1
2 Input: 24
Output: falseExample 5:
1
2 Input: 46
Output: trueNote:
1 <= N <= 10^9
Think
遍历所有可能的2的幂次,如果n为2的幂次的重排列,则其每个数字出现的个数应当是相同的。
Code
1 | bool reorderedPowerOf2(int N) { |
Review
并查集主要两个函数:getRoot,unionFind
-
getRoot的写法固定,即:
1
2
3string getRoot(vector<int> &root, int i){
return root[i] == i ? i : getRoot(root, root[i]);
} -
unionFind函数主要负责判断给定的两个节点是否有相同的root,如果没有则需要将其中一个节点的root值设为另一个节点。