LeetCode(51-100)
51. N-Queens
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens’ placement, where ‘Q’ and ‘.’ both indicate a queen and an empty space respectively.
- Example:
Input: 4
Output: [
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.
- code:
class Solution {
private:
void backtrack(int n, int row, vector<int> ¤t, vector<bool> &cols, vector<vector<int>> &results) {
if (row == n) {
results.push_back(current);
return;
}
for (int i = 0; i < n; i++) {
if (cols[i]) continue;
bool flag = true;
for (int k = 0; k < row; k++) {
if (abs(k - row) == abs(current[k] - i)) {
flag = false;
break;
}
}
if (!flag) continue;
cols[i] = true;
current[row] = i;
backtrack(n, row + 1, current, cols, results);
cols[i] = false;
}
}
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<int>> numbers;
vector<int> current(n, 0);
vector<bool> cols(n, false);
backtrack(n, 0, current, cols, numbers);
vector<vector<string>> results;
for (vector<int> &v : numbers) {
vector<string> curans;
for (int k = 0; k < n; k++) {
char *c = new char[n + 1];
for (int i = 0; i < n; i++) c[i] = '.';
c[n] = 0;
c[v[k]] = 'Q';
curans.push_back(string(c));
delete[] c;
}
results.push_back(curans);
}
return results;
}
};
52. N-Queens II
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return the number of distinct solutions to the n-queens puzzle.
- Example:
Input: 4
Output: 2
Explanation: There are two distinct solutions to the 4-queens puzzle as shown below.
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
- code:
class Solution {
public:
bool isGood(int curi, int curj, int n, vector<vector<char>>& board) {
int colmax = 0;
for (int i = 0; i <= curi; ++i) {
if (board[i][curj] == 'Q')
colmax++;
if (colmax > 1)
return false;
}
int diagl = 0;
for (int i = curi, j = curj; i >= 0 && j >= 0; --i, --j) {
if (board[i][j] == 'Q')
diagl++;
if (diagl > 1)
return false;
}
int diagr = 0;
for (int i = curi, j = curj; i >= 0 && j<n; --i, ++j) {
if (board[i][j] == 'Q')
diagr++;
if (diagr > 1)
return false;
}
return true;
}
void evalNQueens(int cur, int n, vector<vector<char>>& board, int& result) {
if (cur == n) {
result++;
return;
}
for (int j = 0; j<n; ++j) {
board[cur][j] = 'Q';
if (isGood(cur, j, n, board))
evalNQueens(cur + 1, n, board, result);
board[cur][j] = '.';
}
}
int totalNQueens(int n) {
vector<vector<char>> board(n, vector<char>(n, '.'));
int result = 0;
evalNQueens(0, n, board, result);
return result;
}
};
53. Maximum Subarray
Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
- Example:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
- code:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if (nums.size() == 0) return 0;
int maxSum = INT_MIN;
int tempSum = 0;
for (int i = 0; i < nums.size(); i++) {
tempSum += nums[i];
if (tempSum > maxSum) {
maxSum = tempSum;
}
if (tempSum < 0) {
tempSum = 0;
}
}
return maxSum;
}
};
54. Spiral Matrix
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
- Example:
Input:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
Output: [1,2,3,6,9,8,7,4,5]
Input:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
Output: [1,2,3,4,8,12,11,10,9,5,6,7]
- code:
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> res;
if (matrix.empty()) return res;
int m = matrix.size(), n = matrix[0].size();
int up = 0, lf = 0, rg = n - 1, dw = m - 1;
while (1) {
for (int i = lf; i <= rg; i++) res.push_back(matrix[up][i]);
if (++up > dw) break;
for (int i = up; i <= dw; i++) res.push_back(matrix[i][rg]);
if (--rg < lf) break;
for (int i = rg; i >= lf; i--) res.push_back(matrix[dw][i]);
if (--dw < up) break;
for (int i = dw; i >= up; i--) res.push_back(matrix[i][lf]);
if (++lf > rg) break;
}
return res;
}
};
55. Jump Game
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
- Example:
Input: [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
Input: [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.
- code:
class Solution {
public:
bool canJump(vector<int>& nums) {
int size = nums.size();
int step = nums[0];
for (int i = 1; i<size; i++) {
step--;
if (step<0) return false;
if (nums[i]>step)step = nums[i];
}
return true;
}
};
56. Merge Intervals
Given a collection of intervals, merge all overlapping intervals.
- Example:
Input: [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
Input: [[1,4],[4,5]]
Output: [[1,5]]
Explanation: Intervals [1,4] and [4,5] are considerred overlapping.
- code:
class Solution {
public List<Interval> merge(List<Interval> intervals) {
// sort start&end
int n = intervals.size();
int[] starts = new int[n];
int[] ends = new int[n];
for (int i = 0; i < n; i++) {
starts[i] = intervals.get(i).start;
ends[i] = intervals.get(i).end;
}
Arrays.sort(starts);
Arrays.sort(ends);
// loop through
List<Interval> res = new ArrayList<Interval>();
for (int i = 0, j = 0; i < n; i++) { // j is start of interval.
if (i == n - 1 || starts[i + 1] > ends[i]) {
res.add(new Interval(starts[j], ends[i]));
j = i + 1;
}
}
return res;
}
}
57. Insert Interval
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
You may assume that the intervals were initially sorted according to their start times.
- Example:
Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
- code:
class Solution {
public:
vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
vector<Interval> l;
vector<Interval> r;
int start = newInterval.start;
int end = newInterval.end;
for (const Interval& interval : intervals) {
if (interval.end < start)
l.push_back(interval);
else if (interval.start > end)
r.push_back(interval);
else {
start = min(start, interval.start);
end = max(end, interval.end);
}
}
vector<Interval> ans(std::move(l));
ans.emplace_back(start, end);
ans.insert(ans.end(), r.begin(), r.end());
return ans;
}
};
58. Length of Last Word
Given a string s consists of upper/lower-case alphabets and empty space characters ’ ‘, return the length of last word in the string.
If the last word does not exist, return 0.
- Example:
Input: "Hello World"
Output: 5
- code:
class Solution {
public:
int lengthOfLastWord(string s) {
if (s.size() == 0) return 0;
int size = 0;
for (int i = s.size() - 1; i >= 0; i--) {
if (s[i] != ' ')
size++;
else if (s[i] == ' ' && size != 0)
return size;
}
return size;
}
};
59. Spiral Matrix II
Given a positive integer n, generate a square matrix filled with elements from 1 to in spiral order.
- Example:
Input: 3
Output:
[
[ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ]
]
- code:
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int> > result( n, vector<int>(n) );
int num = 1;
for(int i = 0; i < n/2; i++){
for(int j = i; j < n-i; j++)result[i][j] = num++;
for(int j = i+1; j < n-i; j++)result[j][n-1-i] = num++;
for(int j = n-i-2; j >= i; j--)result[n-1-i][j] = num++;
for(int j = n-2-i; j >= i+1; j--)result[j][i] = num++;
}
if(n%2!=0)result[n/2][n/2] = num;
return result;
}
};
60. Permutation Sequence
The set [1,2,3,…,n] contains a total of n! unique permutations.
By listing and labeling all of the permutations in order, we get the following sequence for n = 3:
1. "123"
2. "132"
3. "213"
4. "231"
5. "312"
6. "321"
Given n and k, return the permutation sequence.
- Example:
Input: n = 3, k = 3
Output: "213"
Input: n = 4, k = 9
Output: "2314"
- code:
class Solution {
public String getPermutation(int n, int k) {
if (n == 0) {
return "";
}
List<Integer> list = new ArrayList<Integer>();
StringBuilder sb = new StringBuilder();
int[] facter = new int[n + 1];
facter[0] = 1;
for (int i = 1; i <= n; i++) {
list.add(i);
facter[i] = facter[i - 1] * i;
}
int index = 0;
for (int i = n; i >= 1; i--) {
index = (k - 1) % facter[i] / facter[i - 1];
sb.append(list.get(index));
list.remove(index);
}
return sb.toString();
}
}
61. Rotate List
Given a linked list, rotate the list to the right by k places, where k is non-negative.
- Example:
Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
rotate 1 steps to the right: 5->1->2->3->4->NULL
rotate 2 steps to the right: 4->5->1->2->3->NULL
Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
rotate 1 steps to the right: 2->0->1->NULL
rotate 2 steps to the right: 1->2->0->NULL
rotate 3 steps to the right: 0->1->2->NULL
rotate 4 steps to the right: 2->0->1->NULL
- code:
class Solution {
public ListNode rotateRight(ListNode head, int k) {
if (head == null || head.next == null) {
return head;
}
//find length
int len = 0;
ListNode cur = head;
while (cur != null) {
cur = cur.next;
len++;
}
//determine how many nodes to rotate
int num = k % len;
if (num == 0) {
return head;
}
//rotate
ListNode start = head, end = head;
for (int i = 0; i < num; i++) {
end = end.next;
}
while (end.next != null) {
start = start.next;
end = end.next;
}
ListNode newHead = start.next;
start.next = null;
end.next = head;
return newHead;
}
}
62. Unique Paths
A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).
How many possible unique paths are there?
- Example:
Input: m = 3, n = 2
Output: 3
Explanation:
From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:
1. Right -> Right -> Down
2. Right -> Down -> Right
3. Down -> Right -> Right
Input: m = 7, n = 3
Output: 28
- code:
class Solution {
public:
int uniquePaths(int m, int n) {
if (m == 0 || n == 0) return 0;
if (m == 1 || n == 1) return 1;
vector<vector<int>> grid(n, vector<int>(m, 1));
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
grid[i][j] = grid[i - 1][j] + grid[i][j - 1];
}
}
return grid[n - 1][m - 1];
}
};
63. Unique Paths II
A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).
Now consider if some obstacles are added to the grids. How many unique paths would there be?
An obstacle and empty space is marked as 1 and 0 respectively in the grid.
- Example:
Input:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
Output: 2
Explanation:
There is one obstacle in the middle of the 3x3 grid above.
There are two ways to reach the bottom-right corner:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right
- code:
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int n, m, i, j;
n = obstacleGrid.size();
m = obstacleGrid[0].size();
int arr[n][m];
if (obstacleGrid[0][0] == 0)
arr[0][0] = 1;
else
arr[0][0] = 0;
for (i = 1; i<m; ++i) {
if (obstacleGrid[0][i] == 1)
arr[0][i] = 0;
else
arr[0][i] = arr[0][i - 1];
}
for (i = 1; i<n; ++i) {
if (obstacleGrid[i][0] == 1)
arr[i][0] = 0;
else
arr[i][0] = arr[i - 1][0];
}
for (i = 1; i<n; ++i)
for (j = 1; j<m; ++j) {
if (obstacleGrid[i][j] == 1)
arr[i][j] = 0;
else
arr[i][j] = arr[i - 1][j] + arr[i][j - 1];
}
return arr[n - 1][m - 1];
}
};
64. Minimum Path Sum
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
- Example:
Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7
Explanation: Because the path 1→3→1→1→1 minimizes the sum.
- code:
class Solution {
public:
int minPathSum(vector<vector<int>>& grid)
{
if ((grid.empty() == true) || ((grid.size() == 1) && (grid[0].empty() == true))) {
return 0;
}
else {
if (grid.size() == 1 && grid[0].size() == 1) {
return grid[0][0];
}
else {
std::vector<std::vector<int>> minSumVec(grid.size(), std::vector<int>(grid[0].size(), 0));
minSumVec[0][0] = grid[0][0];
if (grid.size() >= 1 && grid[0].size() > 1) {
for (int i = 1; i<grid[0].size(); ++i) {
minSumVec[0][i] = minSumVec[0][i - 1] + grid[0][i];
}
}
if (grid.size() > 1) {
for (int i = 1; i<grid.size(); ++i) {
minSumVec[i][0] = minSumVec[i - 1][0] + grid[i][0];
}
}
if (grid.size() > 1) {
for (int i = 1; i<grid.size(); ++i) {
for (int j = 1; j<grid[i].size(); ++j) {
minSumVec[i][j] = std::min(minSumVec[i][j - 1], minSumVec[i - 1][j]) + grid[i][j];
}
}
}
int lastVec = minSumVec.size() - 1;
int lastEle = minSumVec[lastVec][minSumVec[lastVec].size() - 1];
return lastEle;
}
}
}
};
65. Valid Number
Validate if a given string is numeric.
Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true
It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.
- code:
class Solution {
public:
bool isNumber(string s) {
int start = 0;
int end = s.size() - 1;
bool dot = false, exp = false, digit = false;
if (start == end && s[start] == '0') return true;
while (start <= end && s[start] == ' ') start++;
while (start <= end && s[end] == ' ') end--;
if (start <= end && (s[start] == '+' || s[start] == '-')) start++;
if (start>end) return false;
if (start == end && s[start] == '0') return true;
for (; start <= end; start++) {
if (s[start] >= '0'&&s[start] <= '9') digit = true;
else if (s[start] == 'e' || s[start] == 'E') {
if (exp == true || digit == false || start == end) return false;
exp = true;
}
else if (s[start] == '.') {
if (dot == true || exp == true) return false;
if (digit == false && start == end) return false;
dot = true;
}
else if (s[start] == '+' || s[start] == '-') {
if (start == end) return false;
if (start>0 && s[start - 1] != 'e' &&s[start - 1] != 'E')
return false;
}
else
return false;
}
return true;
}
};
66. Plus One
Given a non-empty array of digits representing a non-negative integer, plus one to the integer.
The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit.
You may assume the integer does not contain any leading zero, except the number 0 itself.
- Example:
Input: [1,2,3]
Output: [1,2,4]
Explanation: The array represents the integer 123.
Input: [4,3,2,1]
Output: [4,3,2,2]
Explanation: The array represents the integer 4321.
- code:
class Solution {
public:
vector<int> plusOne(vector<int>& digits) {
bool carryon = false;
int last = addOne(digits[digits.size() - 1]);
if (last != 0) {
digits[digits.size() - 1] = last;
return digits;
}
else {
digits[digits.size() - 1] = last;
carryon = true;
int index = digits.size() - 2;
while (carryon && index >= 0) {
int temp = addOne(digits[index]);
if (temp != 0) {
digits[index] = temp;
return digits;
}
else {
digits[index] = temp;
index--;
}
}
if (carryon) {
vector<int> result = { 1 };
for (int i = 0; i<digits.size(); i++) {
result.push_back(digits[i]);
}
return result;
}
}
}
int addOne(int input) {
if (input == 9) {
return 0;
}
else {
input++;
return input;
}
}
};
67. Add Binary
Given two binary strings, return their sum (also a binary string).
The input strings are both non-empty and contains only characters 1 or 0.
- Example:
Input: a = "11", b = "1"
Output: "100"
Input: a = "1010", b = "1011"
Output: "10101"
- code:
class Solution {
public:
string addBinary(string a, string b) {
string result = "";
int aSize = a.size() - 1;
int bSize = b.size() - 1;
int carry = 0;
while (aSize >= 0 || bSize >= 0 || carry) {
carry += aSize >= 0 ? a[aSize--] - '0' : 0;
carry += bSize >= 0 ? b[bSize--] - '0' : 0;
result += char((carry % 2) + '0');
carry /= 2;
}
reverse(result.begin(), result.end());
return result;
}
};
68. Text Justification
Given an array of words and a width maxWidth, format the text such that each line has exactly maxWidth characters and is fully (left and right) justified.
You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ’ ’ when necessary so that each line has exactly maxWidth characters.
Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.
For the last line of text, it should be left justified and no extra space is inserted between words.
Note:
- A word is defined as a character sequence consisting of non-space characters only.
- Each word’s length is guaranteed to be greater than 0 and not exceed maxWidth.
- The input array words contains at least one word.
Example:
Input:
words = ["This", "is", "an", "example", "of", "text", "justification."]
maxWidth = 16
Output:
[
"This is an",
"example of text",
"justification. "
]
Input:
words = ["What","must","be","acknowledgment","shall","be"]
maxWidth = 16
Output:
[
"What must be",
"acknowledgment ",
"shall be "
]
Explanation: Note that the last line is "shall be " instead of "shall be",because the last line must be left-justified instead of fully-justified.Note that the second line is also left-justified becase it contains only one word.
Input:
words = ["Science","is","what","we","understand","well","enough","to","explain",
"to","a","computer.","Art","is","everything","else","we","do"]
maxWidth = 20
Output:
[
"Science is what we",
"understand well",
"enough to explain to",
"a computer. Art is",
"everything else we",
"do "
]
- code:
class Solution {
public:
vector<string> fullJustify(vector<string>& words, int L) {
vector<string> res;
for (int i = 0; i < words.size(); ) {
int k, l;
l = 0;
for (k = 0; i + k < words.size() && l + words[i + k].size() <= L - k; k++) {
l += words[i + k].size();
}
string tmp = words[i];
for (int j = 0; j < k - 1; j++) {
if (i + k >= words.size()) tmp += " ";
else tmp += string((L - l) / (k - 1) + (j < (L - l) % (k - 1)), ' ');
tmp += words[i + j + 1];
}
tmp += string(L - tmp.size(), ' ');
res.push_back(tmp);
i = i + k;
}
return res;
}
};
69. Sqrt(x)
Implement int sqrt(int x).
Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.
- Example:
Input: 4
Output: 2
Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since the decimal part is truncated, 2 is returned.
- code:
class Solution {
public:// 牛顿法 f(x) = x^2 - n = 0
int mySqrt(int x) {
double ans = x;
double delta = 0.0001;
while (fabs(pow(ans, 2) - x) > delta) {
ans = (ans + x / ans) / 2;
}
return ans;
}
70. Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
- Example:
Input: 2
Output: 2
Explanation: There are two ways to climb to the top.
1. 1 step + 1 step
2. 2 steps
Input: 3
Output: 3
Explanation: There are three ways to climb to the top.
1. 1 step + 1 step + 1 step
2. 1 step + 2 steps
3. 2 steps + 1 step
- code:
class Solution {
public:
int climbStairs(int n) {
int f = 0;
int g = 1;
while(n--) {
g = g + f;
f = g - f;
}
return g;
}
};
71. Simplify Path
Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
Corner Cases:
- Did you consider the case where path = “/../”?
In this case, you should return “/”. - Another corner case is the path might contain multiple slashes ‘/’ together, such as “/home//foo/”.
In this case, you should ignore redundant slashes and return “/home/foo”.
- Did you consider the case where path = “/../”?
code:
class Solution {
public:
string simplifyPath(string path) {
string res, tmp;
vector<string> stk;
stringstream ss(path);
while(getline(ss,tmp,'/')) {
if (tmp == "" or tmp == ".") continue;
if (tmp == ".." and !stk.empty()) stk.pop_back();
else if (tmp != "..") stk.push_back(tmp);
}
for(auto str : stk) res += "/"+str;
return res.empty() ? "/" : res;
}
};