Leetcode Solution
Leetcode Solution
Table of Contents
1. Introduction
2. Array
i. Remove Element
ii. Remove Duplicates from Sorted Array
iii. Plus One
iv. Pascal's Triangle
v. Merge Sorted Array
vi. Sum
vii. Find Minimum in Rotated Sorted Array
viii. Largest Rectangle in Histogram
ix. Maximal Rectangle
x. Palindrome Number
xi. Search a 2D Matrix
xii. Search for a Range
xiii. Search Insert Position
xiv. Find Peak Element
3. Bit Manipulation
i. Missing Number
ii. Power of Two
iii. Number of 1 Bits
4. Tree
i. Depth of Binary Tree
ii. Construct Binary Tree
iii. Binary Tree Level Order Traversal
iv. Symmetric Tree
v. Same Tree
vi. Balanced Binary Tree
vii. Path Sum
viii. Binary Tree Depth Order Traversal
ix. Populating Next Right Pointers in Each Node
x. Convert Sorted List/Array to Binary Search Tree
xi. Path Sum II
xii. Flatten Binary Tree to Linked List
xiii. Validate Binary Search Tree
xiv. Recover Binary Search Tree
xv. Binary Tree Path
xvi. Sum Root to Leaf Numbers
5. Dynamic Programming
i. Best Time To Buy And Sell Stock
ii. Unique Paths
iii. Maximum Subarray
iv. Climbing Stairs
2
LeetCode题
v. Triangle
vi. Unique Binary Search Trees
vii. Perfect Squares
6. Backtracking
i. Combination
ii. Subsets
iii. Permutation
7. Greedy
i. Jump Game
ii. Gas Station
iii. Candy
iv. Word Break
8. Linked List
i. Linked List Cycle
ii. Remove Duplicates from Sorted List
iii. Merge Sorted Lists
iv. Reverse Linked List
v. Swap Nodes in Pairs
vi. Sort List
vii. Rotate List
viii. Reorder List
ix. Partition List
x. Add Two Numbers
xi. Copy List with Random Pointer
9. Math
i. Reverse Integer
10. String
i. Add Binary
ii. Basic Calculator II
3
LeetCode题
张晓翀 说应该 门 汉 们为 撬
门 LeetCode 题 这 难 Google
别 码
发现 题 还 记 实这
们 应该 题 记录 识 懂
让 时 举 类
现 备 这 书 LeetCode题 记录 们 LeetCode题 时 历
们 证 书 码 过 时LeetCode 测试 虽 续 为LeetCode测试 变导
题 过 们 实时 进
编 语 C++ 码风 编码规 毕 题 码
懂
LeetCode现 题 们 节 扩 识 这 们 现
书 鉴 时间 实
们 欢 馈 们 东 见 议 欢 Github
issue 们联
Thanks Contributor
陈 collectchen@gmail.com
张晓翀 xczhang07@gmail.com
Maintainer
SiddonTang siddontang@gmail.com
Introduction 4
LeetCode题
Array
Array 5
LeetCode题
Remove Element
Given an array and a value, remove all instances of that > value in place and return the new length.
The order of elements can be changed. It doesn't matter what you leave beyond the new length.
为 选 题 组 value 组长
这题 in place 另 组
简单 两 标i j 历 组 value j记录 时递 i
value 现 时i对应 值 j j 过 历结 这时 j 组
长
class Solution {
public:
int removeElement(int A[], int n, int elem) {
int i = 0;
int j = 0;
for(i = 0; i < n; i++) {
if(A[i] == elem) {
continue;
}
A[j] = A[i];
j++;
}
return j;
}
};
举 简单 组为1 2 2 3 2 4 们 删 2 i j为0
为 为1 A[0] = A[0] i j 1 为2 们递 i 3 时
A[1] = A[3] 3 递 i j 这时 2 递 i 4 时A[2] = A[5]
4 递 i j 这时 组 经 历 毕 结 这时 j 值为3 刚 组 长
Remove Element 6
LeetCode题
Do not allocate extra space for another array, you must do this in place with constant memory.
这 题 题Remove Element 较类 组 删
class Solution {
public:
int removeDuplicates(int A[], int n) {
if(n == 0) {
return 0;
}
int j = 0;
for(int i = 1; i < n; i++) {
if(A[j] != A[i]) {
A[++j] = A[i];
}
}
return j + 1;
}
};
紧 题 样 许 两
题 们 计 记录 2 们
题 处 们 计
class Solution {
public:
int removeDuplicates(int A[], int n) {
if(n == 0) {
return 0;
}
int j = 0;
int num = 0;
for(int i = 1; i < n; i++) {
if(A[j] == A[i]) {
num++;
if(num < 2) {
A[++j] = A[i];
}
} else {
A[++j] = A[i];
num = 0;
}
}
return j + 1;
}
};
Plus One
Given a non-negative number represented as an array of digits, plus one to the number.
The digits are stored such that the most significant digit is at the head of the list.
这 题 简单 进 问题 码
class Solution {
public:
vector<int> plusOne(vector<int> &digits) {
vector<int> res(digits.size(), 0);
int sum = 0;
int one = 1;
for(int i = digits.size() - 1; i >= 0; i--) {
sum = one + digits[i];
one = sum / 10;
res[i] = sum % 10;
}
if(one > 0) {
res.insert(res.begin(), one);
}
return res;
}
};
Plus One 9
LeetCode题
Pascal's Triangle
Given numRows, generate the first numRows of Pascal's triangle.
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
们 规
k层 k
层 值为1
对 k k > 2 层 n n > 1 && n < k A[k][n] A[k][n] = A[k-1][n-1] + A[k-1][n]
规 们 维 组 储 码
class Solution {
public:
vector<vector<int> > generate(int numRows) {
vector<vector<int> > vals;
vals.resize(numRows);
return vals;
}
};
Pascal's Triangle II
Given an index k, return the kth row of the Pascal's triangle.
题 这 们仅仅 k层 O(k) 间 维 组
组滚动计
Pascal's Triangle 10
LeetCode题
设现 组 3层 [1, 3, 3, 1] 们 计 4层 们 计
A[4][2]= A[3][1] + A[3][2] 4 为 组 4这 值 2这
们计 A[4][3] 时 现问题 为这时 A[3][2] 3 4
计 码 简单
class Solution {
public:
vector<int> getRow(int rowIndex) {
vector<int> vals;
vals.resize(rowIndex + 1, 1);
return vals;
}
};
Pascal's Triangle 11
LeetCode题
Note: You may assume that A has enough space (size that is greater or equal to m + n) to hold
additional elements from B. The number of elements initialized in A and B are m and n respectively.
A B 经 组 们 较
为A 够 间 纳A + B 们 标i m+n-1 值 历
A B 谁 i这 时递减i
class Solution {
public:
void merge(int A[], int m, int B[], int n) {
int i = m + n - 1;
int j = m - 1;
int k = n - 1;
while(i >= 0) {
if(j >= 0 && k >= 0) {
if(A[j] > B[k]) {
A[i] = A[j];
j--;
} else {
A[i] = B[k];
k--;
}
} else if(j >= 0) {
A[i] = A[j];
j--;
} else if(k >= 0) {
A[i] = B[k];
k--;
}
i--;
}
}
};
2Sum
Given an array of intergers, find two numbers such that they add up to a specific target number. The
function twoSum should return indices of the two numbers such that they add up to the target,
where index1 must be less than index2 Please note that your returned answers (both index1 and
index2) are not zero-based.
You may assume that each input would have exactly one solution.
题 译 这 题 给 组 值 让 这 组 两 值 这 给 值
标 输 1 标较 较 2 这俩 标 为
题 们 题 键
1. 标值
2. 这两 标
3. 这 题 设 组 这样 们 题 难
题 们
1. 们 标 时 顺 组
2. 为 标值 为 们 标 +1
3. 为 组 这 这 题 难 说 们
两 结 终
题 这 题 难 leetcode 题 们 两 for 环
O(n2) 时间 杂 话 计 这 显 试 brute force
优 题 时 给 们 O(n) 时间 杂 这 题
显 过 馅饼 啦 优 时间 杂 们 牺 间 杂
啦 这 stack queue vector 还 hash_map?
们 这 组 hashmap 环 时间 杂 为O(n), 对 给 组
进 历 针对 们 another_number = target-numbers[i], hashmap find
function 查 这 值 话 进 续 较 详见 码 话 继续查
啦 经摆 这 详见 码
class Solution {
public:
vector<int> twoSum(vector<int> &numbers, int target) {
//边 问题 们 虑边 问题 处
vector<int> ret;
Sum 13
LeetCode题
if(numbers.size() <= 1)
return ret;
// map<key,value> 储numbers index
//这 unordered_map hash_map
unordered_map<int,int> myMap;
for(int i = 0; i < numbers.size(); ++i)
myMap[numbers[i]] = i;
for(int i = 0; i < numbers.size(); ++i)
{
int rest_val = target - numbers[i];
if(myMap.find(rest_val)!=myMap.end())
{
int index = myMap[rest_val];
if(index == i)
continue; // 们 pass 这 值
if(index < i)
{
ret.push_back(index+1); //这 +1 为题 说 non-zero based index
ret.push_back(i+1);
return ret;
}
else
{
ret.push_back(i+1);
ret.push_back(index+1);
return ret;
}
}
}
}
};
记 检查这两 标 为 们 样
3Sum
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all
unique triplets in the array which gives the sum of zero.
Note: Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c) The solution set
must not contain duplicate triplets.
题 译
给 组num 这 组 满 这 num[i]+num[j]+num[k] = 0.
说两
题 两
1. 组
2.
Sum 14
LeetCode题
1. 组triplet
2. 组
1. 为 组 头 们 对 组进
2. 为 组 们 码 对
组 这样 leetcode 时 满 组
map进 处 觉 样 烦 这 给 额 间
时间 杂
对 这 题 为 样 O(n2) 时间 杂 O(n)时间 杂
归 结 实这 two pointers 两 针 动另 题
细节问题 码
class Solution {
public:
//constant space version
vector<vector<int> > threeSum(vector<int> &num) {
vector<vector<int>> ret;
//corner case invalid check
if(num.size() <= 2)
return ret;
//first we need to sort the array because we need the non-descending order
sort(num.begin(), num.end());
Sum 15
LeetCode题
++j;
else
--k;
}
//this while loop also is used to skip the duplication solution
while(i < num.size()-1&&num[i] == num[i+1])
++i;
}
return ret;
}
};
3Sum Closest
Given an array S of n integers, find three integers in S such that the sum is closest to a given
number, target. Return the sum of the three integers. You man assume that each input would have
exactly one solution.
题 译
给 组S 值 这 组 这 给 值 input
这 题 较
1. 两 0.这 对 这 题 较 别
2. 这 题 3Sum 辙 题 们还 头 对 组进
针 动
3. 另 这 题 INT_MAX这 值 这 值 INT_MIN 对应 较 值 值
经 这两 变
这 题 题 3Sum 设 针 两 动另 这 题
东 distance 较这块 tmp distance min distance 较
时间 杂
这 题 3Sum 时间 杂 为O(n2)
Sum 16
LeetCode题
class Solution {
public:
int ret = 0;
//first we suspect the distance between the sum and the target is the largest number in int
int distance = INT_MAX;
sort(num.begin(),num.end()); //sort is needed
for(int i = 0; i < num.size()-2; ++i)
{
int j = i+1;
int k = num.size()-1;
while(j < k)
{
int tmp_val = num[i]+num[j]+num[k];
int tmp_distance;
if(tmp_val < target)
{
tmp_distance = target - tmp_val;
if(tmp_distance < distance)
{
distance = tmp_distance;
ret = num[i]+num[j]+num[k];
}
++j;
}
else if(tmp_val > target)
{
tmp_distance = tmp_val-target;
if(tmp_distance < distance)
{
distance = tmp_distance;
ret= num[i]+num[j]+num[k];
}
--k;
}
else //note: in this case, the sum is 0, 0 means the shortest distance from the sum t
{
ret = num[i]+num[j]+num[k];
return ret;
}
}
}
return ret;
}
};
总结 这 题
1. 对 组进
2. 0 两 组间
Sum 17
LeetCode题
4Sum
Given an array S of n integers, are there elements a, b, c and d in S such that a+b+c+d = target?
Find all unique quadruplets in the array which gives the sume of target.
Note:
题 译
给 组num 标值target 组 组 满
num[a]+num[b]+num[c]+num[d] = target.
这 题 3Sum 辙 过 时间 杂 3Sum 级 对
两 处
1. 对 组进 这样 .
2. 对 处 3Sum 样
题 3Sum.
时间 杂
这 题 选择 间 杂 为1 时间 杂 为O(n3).对 这样 问题 KSum(K>=5),
觉 hash_map 牺 间 杂 换 时间 杂 .
class Solution {
public:
vector<vector<int> > fourSum(vector<int> &num, int target) {
vector<vector<int>> ret;
if(num.size() <= 3) //invalid corner case check
return ret;
sort(num.begin(), num.end()); //cause we need the result in quadruplets should be non-descend
for(int i = 0; i < num.size()-3; ++i)
{
if(i > 0 && num[i] == num[i-1])
continue;
for(int j = i+1; j < num.size()-2; ++j)
{
if(j > i+1 && num[j] == num[j-1])
continue;
Sum 18
LeetCode题
int k = j+1;
int l = num.size()-1;
while(k < l)
{
int sum = num[i]+num[j]+num[k]+num[l];
if(sum == target)
{
vector<int> curr; //create a temporary vector to store the each quadruplets
curr.push_back(num[i]);
curr.push_back(num[j]);
curr.push_back(num[k]);
curr.push_back(num[l]);
ret.push_back(curr);
//the two while loops are used to skip the duplication solutions
do{++k;}
while(k<l && num[k] == num[k-1]);
do{--l;}
while(k<l && num[l] == num[l+1]);
}
else if(sum < target)
++k; //we can do this operation because of we sort the array at the beginnin
else
--l;
}
}
}
return ret;
}
};
码 觉 说 :
问题扩
KSum
2Sum, 3Sum, 3Sum Cloest 还 4Sum 认 题
发现 规 这时 变 KSum问题 们应该 这
们 问题扩 .
Sum 19
LeetCode题
void twoSum(vector<int> &numbers, int begin, int first, int second, int target, vector<vector
if(begin >= numbers.size()-1)
return;
int b = begin;
int e = numbers.size()-1;
while(b < e)
{
int rest = numbers[b]+numbers[e];
if(rest == target)
{
vector<int> tmp_ret;
tmp_ret.push_back(first);
tmp_ret.push_back(second);
tmp_ret.push_back(numbers[b]);
tmp_ret.push_back(numbers[e]);
ret.push_back(tmp_ret);
do{b++;}
while(b<e && numbers[b] == numbers[b-1]);
do{e--;}
while(b<e && numbers[e] == numbers[e+1]);
}
else if(rest < target)
++b;
else
--e;
}
}
给 对 4Sum 们 调 这 function 码 :
class Solution {
public:
void twoSum(vector<int> &numbers, int begin, int first, int second, int target, vector
if(begin >= numbers.size()-1)
return;
int b = begin;
int e = numbers.size()-1;
while(b < e)
{
int rest = numbers[b]+numbers[e];
if(rest == target)
{
vector<int> tmp_ret;
tmp_ret.push_back(first);
tmp_ret.push_back(second);
tmp_ret.push_back(numbers[b]);
tmp_ret.push_back(numbers[e]);
ret.push_back(tmp_ret);
do{b++;}
while(b<e && numbers[b] == numbers[b-1]);
do{e--;}
while(b<e && numbers[e] == numbers[e+1]);
}
else if(rest < target)
Sum 20
LeetCode题
++b;
else
--e;
}
}
vector<vector<int> > fourSum(vector<int> &num, int target) {
vector<vector<int>> ret;
if(num.size() <= 3) //invalid corner case check
return ret;
sort(num.begin(), num.end()); //cause we need the result in quadruplets should be non-descend
for(int i = 0; i < num.size()-3; ++i)
{
if(i > 0 && num[i] == num[i-1])
continue;
for(int j = i+1; j < num.size()-2; ++j)
{
if(j > i+1 && num[j] == num[j-1])
continue;
twoSum(num, j+1, num[i], num[j], target-(num[i]+num[j]), ret);
}
}
return ret;
}
};
KSum. 过 对 n-2 环 这
类 问题
Sum 21
LeetCode题
这题 轮转 组 值 们
码 :
class Solution {
public:
int findMin(vector<int> &num) {
int size = num.size();
if(size == 0) {
return 0;
} else if(size == 1) {
return num[0];
} else if(size == 2) {
return min(num[0], num[1]);
}
int start = 0;
int stop = size - 1;
这题 题 别 们 处 mid start 这
额
码 :
class Solution {
public:
int findMin(vector<int> &num) {
int size = num.size();
if(size == 0) {
return 0;
} else if(size == 1) {
return num[0];
} else if(size == 2) {
return min(num[0], num[1]);
}
int start = 0;
int stop = size - 1;
}
}
这题 终 历 组 查
The largest rectangle is shown in the shaded area, which has area = 10 unit.
这 题 较难 题 简单 对 bar 历
该bar 这时 计 该 积 对 bar 们 处
值 这 O(n2) 铁 过 测试
class Solution {
public:
int largestRectangleArea(vector<int> &height) {
vector<int> s;
// 为0 bar
height.push_back(0);
int sum = 0;
int i = 0;
while(i < height.size()) {
if(s.empty() || height[i] > height[s.back()]) {
s.push_back(i);
i++;
} else {
int t = s.back();
s.pop_back();
//这 还 虑stack为
sum = max(sum, height[t] * (s.empty() ? i : i - s.back() - 1));
}
}
return sum;
}
};
Maximal Rectangle
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and
return its area.
这题 难 题 刚 时 google
这题 阵 1 积 这
0 0 0 0
1 1 1 1
1 1 1 0
0 1 0 0
们 积为6 图 线 围 们 这
0 0 0 0
|--------|
|1 1 1 |1
|1 1 1 |0
|--------|
0 1 0 0
对 哪 题 们 发现 转 图 为[2, 2, 2,
0] 们认为1 0 则 为0 计 这 图 积
们 经 Largest Rectangle in Histogram处
们 图 别 图 结
class Solution {
public:
int maximalRectangle(vector<vector<char> > &matrix) {
if(matrix.empty() || matrix[0].empty()) {
return 0;
}
int m = matrix.size();
int n = matrix[0].size();
Maximal Rectangle 27
LeetCode题
int maxArea = 0;
for(int i = 0; i < m; i++) {
maxArea = max(maxArea, largestRectangleArea(height[i]));
}
return maxArea;
}
int sum = 0;
int i = 0;
while(i < height.size()) {
if(s.empty() || height[i] > height[s.back()]) {
s.push_back(i);
i++;
} else {
int t = s.back();
s.pop_back();
sum = max(sum, height[t] * (s.empty() ? i : i - s.back() - 1));
}
}
return sum;
}
};
Maximal Rectangle 28
LeetCode题
Palindrome Number
Determine whether an integer is a palindrome. Do this without extra space.
题 译: 给 这 为 . 121 122 .
题 :这 题 显 题,计 们 实 这 10
10 这 10 .
1. 负 .
2. 0 .
时间 杂 : logN
码 :
class Solution {
public:
bool isPalindrome(int x) {
if(x < 0)
return false;
else if(x == 0)
return true;
else
{
int tmp = x;
int y = 0;
while(x != 0)
{
y = y*10 + x%10;
x = x/10;
}
if(y == tmp)
return true;
else
return false;
}
}
};
Palindrome Number 29
LeetCode题
Search a 2D Matrix
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following
properties:
Integers in each row are sorted from left to right. The first integer of each row is greater than the last
integer of the previous row. For example,
[
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
题 译: 给 阵 值 这 阵 这 给
值 . 这 阵 .
1. 对 值 .
2. 对 值 .
class Solution {
public:
bool searchMatrix(vector<vector<int> > &matrix, int target) {
/* we set the corner case as below:
1, if the row number of input matrix is 0, we set it false
2, if the colomun number of input matrix is 0, we set it false*/
if(matrix.size() == 0)
return false;
if(matrix[0].size() == 0)
return false;
int rowNumber = 0;
int colNumber = matrix[0].size()-1;
while(rowNumber < matrix.size() && colNumber >= 0)
{
if(target < matrix[rowNumber][colNumber])
--colNumber;
else if(target > matrix[rowNumber][colNumber])
++rowNumber;
else
return true;
}
return false;
}
Search a 2D Matrix 30
LeetCode题
};
Search a 2D Matrix 31
LeetCode题
For example,
这题 组 值 间 围 O(log n) 时间
们 两 查 该值 现 m [m, n) 间
该值 现 码
class Solution {
public:
vector<int> searchRange(int A[], int n, int target) {
if(n == 0) {
return vector<int>({-1, -1});
}
vector<int> v;
int low = 0;
int high = n - 1;
//
while(low <= high) {
int mid = low + (high - low) / 2;
if(A[mid] >= target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
low = low;
high = n - 1;
// 进
while(low <= high) {
int mid = low + (high - low) / 2;
if(A[mid] <= target) {
low = mid + 1;
} else {
high = mid - 1;
}
v.push_back(high);
return v;
}
};
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0
这题 组查 值value 则 对应index 则 组
index 证 组
class Solution {
public:
int searchInsert(int A[], int n, int target) {
int low = 0;
int high = n - 1;
return low;
}
};
Given an input array where num[i] ≠ num[i+1], find a peak element and return its index.
The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.
For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index
number 2.
对 这题 简单 历 组 两边 杂 为O(N) 这
题还 过
class Solution {
public:
int findPeakElement(const vector<int> &num) {
int n = num.size();
if(n == 1) {
return 0;
}
int start = 0;
int end = n - 1;
int mid = 0;
Bit Manipulation
Bit Manipulation 37
LeetCode题
Missing Number
Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing
from the array.
Note: Your algorithm should run in linear runtime complexity. Could you implement it using only
constant extra space complexity?
题 译: 0 n 间 n 应 线 时间 杂
实现 额 间 杂 吗
题 : 观 对 进 扫 较
时间 杂 nlog(n) 满 题
线 时间 杂 对0 n 对给 组 为
这 0 为 时两
0
CPU 费 时钟 运 (XOR)运 题 标签 运
题 运
运 质 0 为0 质
题 0 n这 进 运 对输 组进 运 两
结 进 运 结 为 两 组 对 现 运
0
时间 杂 O(n) 间 杂 O(1)
码 :
class Solution {
public:
int missingNumber(vector<int>& nums) {
int x = 0;
for (int i = 0; i <= nums.size(); i++) x ^= i;
for (auto n : nums) x ^= n;
return x;
}
};
Missing Number 38
LeetCode题
Power of Two
Given an integer, write a function to determine if it is a power of two.
题 译: 给 2 幂
题 :2 幂对应 进 0 1 1 们 输 进
达 这 corner case 输 为负 时 2 幂
时间 杂 O(n) 间 杂 O(1)
码 :
class Solution {
public:
bool isPowerOfTwo(int n) {
if (n < 0) return false;
bool hasOne = false;
while (n > 0) {
if (n & 1) {
if (hasOne) {
return false;
}
else {
hasOne = true;
}
}
n >>= 1;
}
return hasOne;
}
};
Power of Two 39
LeetCode题
Number of 1 Bits
Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known
as the Hamming weight). For example, the 32-bit integer 11 has binary representation
00000000000000000000000000001011 , so the function should return 3.
题 译: 给 进 1 32 11 进 达
00000000000000000000000000001011 应该 3
题 : 设输 为n n 1 进 (AND)运 为1 话
计 变 n 动 n变为0时 终 输 结
时间 杂 O(n) 间 杂 O(1)
码 :
class Solution {
public:
int hammingWeight(uint32_t n) {
int count = 0;
while (n > 0) {
count += n & 1;
n >>= 1;
}
return count;
}
};
Number of 1 Bits 40
LeetCode题
Tree
树 线 结构 应 计 术 领 树 实现 查
库 统 红 树
树 义 递归 树 递归 实现 递归
较 时 递归
树 题 树 历 树 查 树
Tree 41
LeetCode题
The maximum depth is the number of nodes along the longest path from the root node down to the
farthest leaf node.
这题 们 树 节 远 节
对 这题 们 递归 历 树 达 节 时 记录 们
class Solution {
public:
int num;
int maxDepth(TreeNode *root) {
if(!root) {
return 0;
}
// num为 值
num = numeric_limits<int>::min();
travel(root, 1);
return num;
}
if(node->left) {
travel(node->left, level + 1);
}
if(node->right) {
travel(node->right, level + 1);
}
}
};
The minimum depth is the number of nodes along the shortest path from the root node down to the
nearest leaf node.
这题 题 样 别 节 节 们 历
class Solution {
public:
int n;
int minDepth(TreeNode *root) {
if(!root) {
return 0;
}
// 值
n = numeric_limits<int>::max();
int d = 1;
depth(root, d);
return n;
}
if(node->left) {
d++;
depth(node->left, d);
d--;
}
if(node->right) {
d++;
depth(node->right, d);
d--;
}
}
};
构 树 们 树 历 树
1
--------|-------
2 3
----|---- ----|----
4 5 6 7
历 1245367
历 4251637
续 历 4526731
这 题 们 树 历 历 结 构 这颗 树
棵 树为 们 发现 对 历 说 节 1
们 历 结 1 树
树
们 历 425 时发现 历 结 应 顺 样
452 们 发现 历 2 该 树 节
说 树 对 树 们 637 时发现 历 对应 顺
样 为673 3 这颗 树 节
过 过 续 历 节 历 节 两 时 对
应 历 两 递归 树
class Solution {
public:
unordered_map<int, int> m;
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
if(postorder.empty()) {
return NULL;
}
return root;
}
};
这 们 为 证 历结 节 们 hash map
这题 题类 过 历 历 结 构 树 们 历 值
节 处
过 历 节
过 节 历 两
对
class Solution {
public:
unordered_map<int, int> m;
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
if(preorder.empty()) {
return NULL;
}
TreeNode* build(vector<int>& preorder, int s0, int e0, vector<int> &inorder, int s1,
if(s0 > e0 || s1 > e1) {
return NULL;
}
return root;
}
};
这两 题 树 历 节 过 历
两 树 码 时 对
3
/ \
9 20
/ \
15 7
[
[3],
[9,20],
[15,7]
]
题 译: 给 颗 树 维 组 这 维 组 树 层
. 经 给 .
为:
1. 对 棵树 们 层 节 维 组 们 维 组
这 维 组 们 这颗树 维 组.
2. 题 为 , 们 边 节 边 节 .
3. 对 这 题 们 DFS 这颗树 DFS对 层 历 这样节
间 杂 .
时间 杂 : 两 DFS 们 时间 杂 为O(n).
码 :
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
/* for this question, we need to construct the ret vector first
thus, we need to know the depth of this tree, we write a simple
function to calculate the height of this tree */
vector<vector<int> > levelOrder(TreeNode *root) {
int depth = getHeight(root);
vector<vector<int>> ret(depth);
if(depth == 0) //invalid check
return ret;
getSolution(ret,root,0);
return ret;
}
3
/ \
9 20
/ \
15 7
[
[15,7],
[9,20],
[3]
题 译: 给 颗 树 维 组 这 维 组 满 这 维 组 维
组 这 树 层 类 应该
码 :
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int> > levelOrderBottom(TreeNode *root) {
int depth = height(root);
vector<vector<int>> ret(depth);
if(depth == 0)
return ret;
DFS(ret,ret.size()-1, root);
return ret;
}
3
/ \
9 20
/ \
15 7
[
[3],
[20,9],
[15,7]
]
两题 这题应该 简单 们 zigzag 转 码
class Solution {
public:
vector<vector<int> > vals;
vector<vector<int> > zigzagLevelOrder(TreeNode *root) {
build(root, 1);
// 转
for(int i = 1; i < vals.size(); i+=2) {
reverse(vals[i].begin(), vals[i].end());
}
return vals;
}
vals[level - 1].push_back(node->val);
if(node->left) {
build(node->left, level + 1);
}
if(node->right) {
build(node->right, level + 1);
}
}
};
Symmetric Tree
Given a binary tree, check whether it is a mirror of itself(ie, symmetric around its center)
1
/ \
2 2
/ \ / \
3 4 4 3
1
/ \
2 2
\ \
3 3
题 译 棵树 镜 两 这 题 题
简单 .
题 : 递归: 这 题 别 现 这 简单 题 节 们
.
1. 两 节 .
2. 节 节 .
3. 节 节 .
环: 这 题 难 环 环 们 须 额 储 间 键
对 这 题 们 样 储 间
递归 对 层 满 们 认为这棵树 镜 树.
递归 码 :
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
Symmetric Tree 52
LeetCode题
*/
class Solution {
public:
bool isSymmetric(TreeNode *root) {
if(root == NULL)
return true;
return Helper(root->left,root->right);
}
};
环 : 们 绍 这 题 环 对 环 们 满 对 层进 check
递归 树 环 历 们 FIFO queue 为临时 间 储变 这 题 们 选
queue 们 两 queue 为 们 对 时进 检查 显 queue 够
实现细节 咱们还 码 码 释 .
环 码 :
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode *root) {
if(root == NULL)
return true;
TreeNode* n1 = root->left;
TreeNode* n2 = root->right;
if(!n1&&!n2)
return true;
if((!n1&&n2)||(n1&&!n2))
return false;
queue<TreeNode*> Q1;
queue<TreeNode*> Q2;
Q1.push(n1);
Q2.push(n2);
while(!Q1.empty() && !Q2.empty())
Symmetric Tree 53
LeetCode题
{
TreeNode* tmp1 = Q1.front();
TreeNode* tmp2 = Q2.front();
Q1.pop();
Q2.pop();
if((!tmp1&&tmp2) || (tmp1&&!tmp2))
return false;
if(tmp1&&tmp2)
{
if(tmp1->val != tmp2->val)
return false;
Q1.push(tmp1->left);
Q1.push(tmp1->right); //note: this line we should put the mirror sequence in two queu
Q2.push(tmp2->right);
Q2.push(tmp2->left);
}
}
return true;
}
};
Symmetric Tree 54
LeetCode题
Same Tree
Given two binary trees, write a function to check if they are equal or not. Two binary trees are
considered equal if they are structurally identical and the nodes have the same values.
题 :这 题 规 简单 们 DFS 历这两棵树 .
时间 杂 : 为 DFS, 时间 杂 为O(n)
码 :
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode *p, TreeNode *q) {
if(p == NULL && q == NULL)
return true;
else if(p == NULL || q == NULL)
return false;
if(p->val == q->val)
{
bool left = isSameTree(p->left, q->left);
bool right = isSameTree(p->right,q->right);
return left&&right;
}
return false;
}
};
Same Tree 55
LeetCode题
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the
two subtrees of every node never differ by more than 1.
题 译: 给 颗 树 检测这棵树 树. 对 这 问题, 颗 树
义 节 树 1.
时间 杂 : 运 DFS 时间 杂 为O(n).
码 :
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isBalanced(TreeNode *root) {
//corner case check
if(root == NULL)
return true;
int isBalanced = getHeight(root);
if(isBalanced != -1)
return true;
else
return false;
}
else
return diffHeight = (rightHeight>leftHeight?rightHeight:leftHeight)+1;
}
};
Path Sum
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all
the values along the path equals the given sum.
For example: Given the below binary tree and sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.
题 译: 给 颗 树 值 这棵树 这样 root
节 给 sum值.
题 :这 题 规 DFS .
时间 杂 : O(n)
码 :
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool hasPathSum(TreeNode *root, int sum) {
if(root == NULL)
return false;
return DFS(sum, 0, root);
}
Path Sum 58
LeetCode题
else
return false;
}
bool leftPart = DFS(target, sum, root->left);
bool rightPart = DFS(target, sum, root->right);
return leftPart||rightPart;
}
};
Path Sum 59
LeetCode题
1
\
2
/
3
return [1,2,3].
给 颗 树 进 历
为 递归 们 stack 态
对 历 节 访问 树 树 访问 节 时 们
树压栈 这样访问 树 对应 树
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> vals;
if(root == NULL) {
return vals;
}
vector<TreeNode*> nodes;
// root压栈
nodes.push_back(root);
while(!nodes.empty()) {
TreeNode* n = nodes.back();
vals.push_back(n->val);
//访问 该节 栈
nodes.pop_back();
// 树 压栈
if(n->right) {
nodes.push_back(n->right);
}
// 树 压栈
if(n->left) {
nodes.push_back(n->left);
}
}
return vals;
}
};
对 历 历 树 节 树 们 stack记录 历
节 树 历 stack弹 节 树 历
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> vals;
if(root == NULL) {
return vals;
}
vector<TreeNode*> nodes;
TreeNode* p = root;
while(p || !nodes.empty()) {
//这 历 树 节 压栈
while(p) {
nodes.push_back(p);
p = p->left;
}
if(!nodes.empty()) {
p = nodes.back();
vals.push_back(p->val);
// 节 弹 获 树
nodes.pop_back();
p = p->right;
}
}
return vals;
}
};
对 历 历 树 树 节 历 节 时 们
树压栈 树压栈 这 栈 规则 对 节 说 栈
对 节 说 们 变 记录 栈 节 栈 节 该 节
树 树 该 节 栈 则这 节 访问 节 树 别压栈
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> vals;
if(root == NULL) {
return vals;
}
vector<TreeNode*> nodes;
TreeNode* pre = NULL;
nodes.push_back(root);
while(!nodes.empty()) {
TreeNode* p = nodes.back();
// pre 们 栈
if((p->left == NULL && p->right == NULL) ||
(pre != NULL && (pre == p->left || pre == p->right))) {
vals.push_back(p->val);
nodes.pop_back();
pre = p;
} else {
// 树压栈
if(p->right != NULL) {
nodes.push_back(p->right);
}
// 树压栈
if(p->left != NULL) {
nodes.push_back(p->left);
}
}
}
return vals;
}
};
总结
树 历 过递归 栈 较 还 栈
过 说
struct TreeLinkNode {
TreeLinkNode *left;
TreeLinkNode *right;
TreeLinkNode *next;
}
Populate each next pointer to point to its next right node. If there is no next right node, the next
pointer should be set to NULL.
Note:
You may only use constant extra space. You may assume that it is a perfect binary tree (ie, all
leaves are at the same level, and every parent has two children). For example, Given the following
perfect binary tree,
1
/ \
2 3
/ \ / \
4 5 6 7
1 -> NULL
/ \
2 -> 3 -> NULL
/ \ / \
4->5->6->7 -> NULL
这题 棵 树 next 针连 边 节 们 发现 规
节 节 树 next 该 节 树 4
next 2 树5
节 节 树 next 该 节 next节 树 5
next 2 next 3 树
class Solution {
public:
TreeLinkNode* p = root;
TreeLinkNode* first = NULL;
while(p) {
//记录 层 树
if(!first) {
first = p->left;
}
// 树 next 节
if(p->left) {
p->left->next = p->right;
} else {
// 节 历结
break;
}
// next 设 树 next
if(p->next) {
p->right->next = p->next->left;
p = p->next;
continue;
} else {
//转 层
p = first;
first = NULL;
}
}
}
};
Note:
You may only use constant extra space. For example, Given the following binary tree,
1
/ \
2 3
/ \ \
4 5 7
1 -> NULL
/ \
2 -> 3 -> NULL
/ \ \
4-> 5 -> 7 -> NULL
题 这题 树 树 们 first 针 层
时 另 lst 针 该层 历 们 处 设 last next 针
码 :
class Solution {
public:
void connect(TreeLinkNode *root) {
if(!root) {
return;
}
TreeLinkNode* p = root;
TreeLinkNode* first = NULL;
TreeLinkNode* last = NULL;
while(p) {
//设 层
if(!first) {
if(p->left) {
first = p->left;
} else if(p->right) {
first = p->right;
}
}
if(p->left) {
// last 则设 last next
if(last) {
last->next = p->left;
}
//last为left
last = p->left;
}
if(p->right) {
// last 则设 last next
if(last) {
last->next = p->right;
}
//last为right
last = p->right;
}
// next 则转 next
if(p->next) {
p = p->next;
} else {
//转 层
p = first;
last = NULL;
first = NULL;
}
}
}
};
实 们 题 题 题 样 题
这题 链 转 树 们 对 树 说 树
节 树 节 们 链 间节 这 节 链
树 则 树 们继续递归处 应 够构 对应 树
class Solution {
public:
return node;
}
};
这题类 题 样 题 对 组 说 间节 码
class Solution {
public:
return node;
}
};
Path Sum II
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given
sum.
For example: Given the below binary tree and sum = 22.
5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
return
[
[5,4,11,2],
[5,8,4,5]
]
题 译 给 树 给 值 节 节 这 给 值 .
让读 这 题 .
时间 杂 : O(n)
码 :
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int> > pathSum(TreeNode *root, int sum) {
vector<vector<int>> ret;
if(root == NULL)
return ret;
vector<int> curr;
DFS(ret,curr,sum,0,root);
Path Sum II 70
LeetCode题
return ret;
}
void DFS(vector<vector<int>>& ret, vector<int> curr, int sum, int tmpsum, TreeNode* root)
{
if(root == NULL)
return;
tmpsum+=root->val;
curr.push_back(root->val);
if(tmpsum == sum)
{
if(root->left == NULL&&root->right == NULL)
{
ret.push_back(curr);
return;
}
}
DFS(ret,curr,sum,tmpsum,root->left);
DFS(ret,curr,sum,tmpsum,root->right);
}
};
Path Sum II 71
LeetCode题
1
/ \
2 5
/ \ \
3 4 6
1
\
2
\
3
\
4
\
5
\
6
给 颗 树 处 们 处 节 顺 实 历 树
们 历 树 时处 码
class Solution {
public:
void flatten(TreeNode *root) {
if(!root) {
return;
}
vector ns;
TreeNode dummy(0);
TreeNode* n = &dummy;
ns.push_back(root);
while(!ns.empty()) {
TreeNode* p = ns.back();
ns.pop_back();
// 载 树
n->right = p;
n = p;
// 树压栈
if(p->right) {
ns.push_back(p->right);
p->right = NULL;
}
// 树压栈
if(p->left) {
ns.push_back(p->left);
p->left = NULL;
}
}
}
};
The left subtree of a node contains only nodes with keys less than the node's key.
The right subtree of a node contains only nodes with keys greater than the node's key.
Both the left and right subtrees must also be binary search trees.
这题 树 较简单 题
们 过递归 棵树 码
class Solution {
public:
bool isValidBST(TreeNode *root) {
return valid(root, numeric_limits<int>::min(), numeric_limits<int>::max());
}
Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
这题 颗 树 两 换节 们 对 颗 树 说
历 输 值 递 们 历输 输 结 两
输 结 换这两 节
这题 O(1) 间 历 递归 栈 O(N) 间
这 们 Morris Traversal 进 树 历
节 为 则输 节 为 节
节 为 节 树 节 历 驱节
节 树 边 节
驱节 为 则 设 为 节 节 为
驱节 为 节 则 驱节 设为 输 节 节
为
过 节 为 递归 时 们 时 记录错误 节 们 节
问题 对 历 说 设 节 为cur 驱节 为pre cur 值
pre 值 cur pre 换
class Solution {
public:
void recoverTree(TreeNode *root) {
TreeNode* cur = 0;
TreeNode* pre = 0;
TreeNode* p1 = 0;
TreeNode* p2 = 0;
TreeNode* preCur = 0;
if(!root) {
return;
}
cur = root;
while(cur) {
if(!cur->left) {
//记录p1 p2
if(preCur && preCur->val > cur->val) {
if(!found) {
p1 = preCur;
found = true;
}
p2 = cur;
}
preCur = cur;
cur = cur->right;
} else {
pre = cur->left;
while(pre->right && pre->right != cur) {
pre = pre->right;
}
if(!pre->right) {
pre->right = cur;
cur = cur->left;
} else {
//记录p1 p2
if(preCur->val > cur->val) {
if(!found) {
p1 = preCur;
found = true;
}
p2 = cur;
}
preCur = cur;
pre->right = NULL;
cur = cur->right;
}
}
}
1
/ \
2 3
\
5
["1->2->5", "1->3"]
题 译 给 棵 树 节 节
题 题 树 历问题 优
栈 记录 历过 访问过 节 递归 访问 节 节 节 则输 记录
层 弹 栈顶 C++ vector 进 码
std::stack类 实现
/**
* 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<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
if (root == nullptr) return result;
vector<int> path;
bfs(root, path, result);
return result;
}
private:
// 递归 优
void bfs(TreeNode* node, vector<int>& path, vector<string>& result) {
if (node == nullptr) return;
path.push_back(node->val);
// 辅
string generatePath(vector<int> path) {
stringstream ss;
int i;
for (i = 0; i < path.size() - 1; i++) ss << path[i] << "->";
ss << path[i];
return ss.str();
}
};
1
/ \
2 3
The root-to-leaf path 1->2 represents the number 12 . The root-to-leaf path 1->3 represents the
number 13 . Return the sum = 12 + 13 = 25.
题 译 给 棵 树 仅 0 9这 节 节
1->2->3 值123 值 1->2 值12
1->3 值13 们 25
题 : 节 节 历 优 (DFS) 题 历过 记录
达 节 时 记录 转换 值
时间 杂 : O(n)
码 :
/**
* 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:
int sumNumbers(TreeNode* root) {
vector<int> arr;
int sum = 0;
dfs(root, arr, sum);
return sum;
}
};
Dynamic Programming
Dynamic Programming 81
LeetCode题
If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the
stock), design an algorithm to find the maximum profit.
这 卖 题 题 们 进 获 润 们
买 卖 买 卖
对 这 题 还 较简单 们 历 组 过 变 记录 时
润 值 较
class Solution {
public:
int maxProfit(vector<int> &prices) {
if(prices.size() <= 1) {
return 0;
}
if(profit < 0) {
return 0;
}
return profit;
}
};
Design an algorithm to find the maximum profit. You may complete as many transactions as you like
(ie, buy one and sell one share of the stock multiple times). However, you may not engage in
multiple transactions at the same time (ie, you must sell the stock before you buy again).
这题 对 题 说 这 为啥 II 为 们 i 买 发现
i+1 i 润
class Solution {
public:
int maxProfit(vector<int> &prices) {
int len = (int)prices.size();
if(len <= 1) {
return 0;
}
int sum = 0;
for(int i = 1; i < len; i++) {
if(prices[i] - prices[i - 1] > 0) {
sum += prices[i] - prices[i - 1];
}
}
return sum;
}
};
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note: You may not engage in multiple transactions at the same time (ie, you must sell the stock
before you buy again).
这题 题 难 题 许两 许 题 题
题 们 [0,1,...,i] 间 润 时 扫 [i,i+1,...,n-1]
润 两 该题
class Solution {
public:
int maxProfit(vector<int> &prices) {
int len = (int)prices.size();
if(len <= 1) {
return 0;
}
vector<int> profits;
profits.resize(len);
// 们 历
// profits
int minP = prices[0];
int sum = numeric_limits<int>::min();
for(int i = 1; i < len; i++) {
minP = min(minP, prices[i - 1]);
sum = profits[i];
}
// 历
for(int i = len - 2; i >= 0; i--) {
maxP = max(maxP, prices[i + 1]);
sum2 = max(sum2, maxP - prices[i]);
if(sum2 > 0) {
//这 们 profits
// 额
profits[i] = profits[i] + sum2;
sum = max(sum, profits[i]);
}
}
卖 1 3 经 动态规 笔 这 还 识积 举 动态规
这 笔 续 续补
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).
class Solution {
public:
int uniquePaths(int m, int n) {
int dp[m][n];
// dp m x 1 为1
for(int i = 0; i < m; i++) {
dp[i][0] = 1;
}
// dp 1 x n 为1
for(int j = 0; j < n; j++) {
dp[0][j] = 1;
}
Unique Paths II
Now consider if some obstacles are added to the grids. How many unique paths would there be?
这题 题 别 过
Unique Paths 85
LeetCode题
码 :
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
if(obstacleGrid.empty() || obstacleGrid[0].empty()) {
return 0;
}
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
int dp[m][n];
// dp 时 obstacleGrid 值
dp[0][0] = (obstacleGrid[0][0] == 0 ? 1 : 0);
// 们 m x 1 1 x n
for(int i = 1; i < m; i++) {
dp[i][0] = ((dp[i - 1][0] == 1 && obstacleGrid[i][0] == 0) ? 1 : 0);
}
Note: You can only move either down or right at any point in time.
Unique Paths 86
LeetCode题
class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
if(grid.empty() || grid[0].empty()) {
return 0;
}
int dp[row][col];
dp[0][0] = grid[0][0];
for(int i = 1; i < row; i++) {
dp[i][0] = dp[i - 1][0] + grid[i][0];
}
Unique Paths 87
LeetCode题
Maximum Subarray
Find the contiguous subarray within an array (containing at least one number) which has the largest
sum.
For example, given the array [−2,1,−3,4,−1,2,1,−5,4], the contiguous subarray [4,−1,2,1] has the
largest sum = 6.
码 :
class Solution {
public:
int maxSubArray(int A[], int n) {
int sum = 0;
int m = INT_MIN;
return m;
}
};
1. 值 A[left, mid - 1]
2. 值 A[mid + 1, right]
3. 值 过 mid 们 计 [left, mid - 1] 间 值 [mid + 1, right] 值
mid 总 值
们 对 1 2 们 过递归 3 结 较
值
码 :
class Solution {
public:
Maximum Subarray 88
LeetCode题
int sum = 0;
int mlmax = 0;
// [left, mid - 1] 值
for(int i = mid - 1; i >= left; i--) {
sum += A[i];
mlmax = max(mlmax, sum);
}
sum = 0;
int mrmax = 0;
// [mid + 1, right] 值
for(int i = mid + 1; i <= right; i++) {
sum += A[i];
mrmax = max(mrmax, sum);
}
For example, given the array [2,3,-2,4], the contiguous subarray [2,3] has the largest product = 6.
这题 组 间 积 对 们 负 负 变 这题
时 们 维护两 变 值 值 值 为负
负 值 变 值 值则变 值
们 动态 这样
Maximum Subarray 89
LeetCode题
码 :
class Solution {
public:
int maxProduct(int A[], int n) {
if(n == 0){
return 0;
} else if(n == 1) {
return A[0];
}
int p = A[0];
int maxP = A[0];
int minP = A[0];
for(int i = 1; i < n; i++) {
int t = maxP;
maxP = max(max(maxP * A[i], A[i]), minP * A[i]);
minP = min(min(t * A[i], A[i]), minP * A[i]);
p = max(maxP, p);
}
return p;
}
};
Maximum Subarray 90
LeetCode题
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?
这 题 实 问题 题 较简单 们 dp
dp[1] = 1, dp[2] = 2
class Solution {
public:
int climbStairs(int n) {
int f1 = 2;
int f2 = 1;
if(n == 1) {
return f2;
} else if(n == 2) {
return f1;
}
int fn;
for(int i = 3; i <= n; i++) {
fn = f1 + f2;
f2 = f1;
f1 = fn;
}
return fn;
}
};
Climbing Stairs 91
LeetCode题
Triangle
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to
adjacent numbers on the row below.
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
这题 们 顶 O(n) 间
这题 两 顶
顶 题 们 层 们 选择邻 进 1
3 邻 6 5
们 设dp[m][n] m n 节 们 dp
为 O(n) 间 们 滚动计 组 层
Pascal's Triangle 们 为 计 时 值 们 计
class Solution {
public:
int minimumTotal(vector<vector<int> > &triangle) {
int row = triangle.size();
if(row == 0) {
return 0;
}
// 为 值
vector<int> total(row, INT_MAX);
total[0] = triangle[0][0];
int minTotal = INT_MAX;
for(int i = 1; i < row; i++) {
for(int j = i; j >= 0; j--) {
if(j == 0) {
total[j] = total[j] + triangle[i][j];
} else {
Triangle 92
LeetCode题
// 层total[i]为INT_MAX 响 值
total[j] = min(total[j - 1], total[j]) + triangle[i][j];
}
}
}
for(int i = 0; i < row; i++) {
minTotal = min(minTotal, total[i]);
}
return minTotal;
}
};
别 顶 另 简单 dp 为
们 组滚动计
class Solution {
public:
int minimumTotal(vector<vector<int> > &triangle) {
if(triangle.empty()) {
return 0;
}
int row = triangle.size();
vector<int> dp;
dp.resize(row);
// 层
for(int i = 0; i < dp.size(); i++) {
dp[i] = triangle[row-1][i];
}
Triangle 93
LeetCode题
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
这 题 给 n 树 储1 n
刚 这题 时 虑 树 质 对 i为 节 树
树 值 i [0, i - 1] 间 树 值 i [i + 1, n] 设 树
m 树 n 则对 i为 节 树总 mxn
们 dp[i] i 节 树 dp 为:
class Solution {
public:
int numTrees(int n) {
vector<int> dp(n + 1, 0);
//dp
dp[0] = 1;
dp[1] = 1;
return dp[n];
}
};
For example, Given n = 3, your program should return all 5 unique BST's shown below.
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
这题 题
们 对 n i 为 树[0, i - 1] x 树[i + 1, n]
们 i 树 树 i 这 递归
码
class Solution {
public:
vector<TreeNode *> generateTrees(int n) {
return generate(1, n);
}
//获 树 树 root为i 节
for(int j = 0; j < l.size(); j++) {
for(int k = 0; k < r.size(); k++) {
TreeNode* n = new TreeNode(i);
n->left = l[j];
n->right = r[k];
vs.push_back(n);
}
}
}
return vs;
}
};
Perfect Squares
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16,
...) which sum to n. For example, given n = 12 , return 3 because 12 = 4 + 4 + 4 ; given n =
13 , return 2 because 13 = 4 + 9 .
题 译 给 n 1 4 9 16…… n
给 n = 12 3 为 12 = 4 + 4 + 4 给 n = 13 2 为 13 = 4 + 9
题 题 较 n 组 过
n 换 问题 凑 齐 话 1 总
12 题 给 4+4+4 3 组 9+1+1+1
4
另 穷举 n 组
为n 组 组 n m 话 这 时间 杂
O(m^m) 显 穷举 时间 杂 过 观 举 过 组 显
优 12 12 1 另 们 够记录 经 组
础 这 动态规
说 们 组 记录 结 为 穷( INT_MAX ) 层 环变 i 0 n
层 环变 j i 础 过n i + j*j 这
组 值 i 值 这两 间较
值较 说 们 经 过 穷 则 话 说
i 础 j i
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n + 1, INT_MAX);
dp[0] = 0;
for (int i = 0; i <= n; i++) {
for (int j = 1; i + j * j <= n; j++) {
dp[i + j * j] = min(dp[i + j * j], dp[i] + 1);
}
}
return dp[n];
}
};
Perfect Squares 96
LeetCode题
Backtracking
Backtracking 97
LeetCode题
Combination
这 section 们 过 leetcode 类 combination这 题 这类题应该归结为
DFS+Backtracking 边 处
讨论 题Combination.
Combination
Given two integers n and k, return all possible combinations of k numbers out of 1,2,...,n.
题 译: 给 两 组n k k 组 combination 实应该 组 .这
combination应该 组 这k n 选k 题 这 k应该
n(这 validation check ).
题 : 这 题 应该 递归 . 环 这 时间 杂 应该
较 . 这 递归 层 层 处 们 环 1
combination 2 类 对n DFS, n-1 DFS...
应该 对n(n-1)...*1 DFS. 们 减 时间.
码 :
class Solution {
public:
vector<vector<int> > combine(int n, int k) {
vector<vector<int>> ret;
if(n <= 0) //corner case invalid check
return ret;
vector<int> curr;
DFS(ret,curr, n, k, 1); //we pass ret as reference at here
return ret;
}
Combination 98
LeetCode题
};
Combination Sum
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C
where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
题 译: 给 组C 标值T, 满 组 组 T,
C 选择
2. 组 满 .
3. 组 .
题 :这 题 combination 这
们进 实现function 时 问题 说 传 递归 combination.
时间 杂 : 说 combination 时间 杂 .O(n!)
码 :
class Solution {
public:
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
vector<vector<int>> ret;
//corner case invalid check
if(candidates.size() == 0 || target < 0)
return ret;
Combination 99
LeetCode题
vector<int> curr;
sort(candidates.begin(),candidates.end()); //because the requirments need the elements should
BackTracking(ret,curr,candidates,target,0);
return ret;
}
/* we use reference at here because the function return type is 0, make the code understand easil
void BackTracking(vector<vector<int>>& ret, vector<int> curr, vector<int> candidates,
{
if(target == 0)
{
ret.push_back(curr);
return;
}
else if(target < 0) //save time
return;
};
Combination Sum II
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in
C where the candidate numbers sums to T.
Note:
2. Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
题 译: 给 组C 值T, 这 满 组 值
.
Combination 100
LeetCode题
3. 终 组.
码 :
class Solution {
public:
vector<vector<int> > combinationSum2(vector<int> &num, int target) {
vector<vector<int>> ret;
if(num.size() == 0 || target < 0) //invalid corner case check
return ret;
vector<int> curr;
sort(num.begin(), num.end());
BackTracking(ret,curr,num,target,0);
return ret;
}
};
Combination 101
LeetCode题
题 :这 题 给 题 combination 们
dictionary, 查 . combination 对 dictionary 查 对应 说
.
题 : 组 构 这 dictionary 标 标为2
这 对应 :dic[2] = "abc". 给 转换为int类 查
这 对应 . 构 时 们 dic[0] = "", dic[1] = "".这两
case 为电话键盘 这两 对应 .
时间 杂 : O(3^n)
码 :
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> ret;
/* for this question, we need to create a look-up dictionary */
vector<string> dic;
string tmp;
dic.push_back(" ");
dic.push_back(" ");
dic.push_back("abc");
dic.push_back("def");
dic.push_back("ghi");
dic.push_back("jkl");
dic.push_back("mno");
dic.push_back("pqrs");
dic.push_back("tuv");
dic.push_back("wxyz");
combinations(ret,tmp,digits,dic,0);
return ret;
}
Combination 102
LeetCode题
tmp.pop_back();
}
}
};
Combination 103
LeetCode题
Subsets
Given a set of distinct integers, S, return all possible subsets.
Note: Elements in a subset must be in non-descending order. The solution set must not contain
duplicate subsets. For example, If S = [1,2,3], a solution is:
>
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
>
这题 实 时
们 对 对 n 们 n-1
认为 节 们 历 历 时 续 n-2
节 历处 继续处 处
们 样 处
[1, 2, 3] 1 2 3 1 节 2 [1, 2]
3 2 节 3 [1, 2, 3] 3 [1, 3]
1处 们 样 处 2 3
class Solution {
public:
vector<vector<int> > res;
vector<vector<int> > subsets(vector<int> &S) {
if(S.empty()) {
return res;
}
sort(S.begin(), S.end());
//别
res.push_back(vector<int>());
vector<int> v;
Subsets 104
LeetCode题
generate(0, v, S);
return res;
}
res.push_back(v);
generate(i + 1, v, S);
v.pop_back();
}
}
};
Subsets II
Given a collection of integers that might contain duplicates, S, return all possible subsets.
Note: Elements in a subset must be in non-descending order. The solution set must not contain
duplicate subsets. For example, If S = [1,2,2], a solution is:
>
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
>
这题 题 别 们 实 简单
处 历 节 时 发现 历 续 过 码
class Solution {
public:
vector<vector<int> > res;
Subsets 105
LeetCode题
return res;
}
sort(S.begin(), S.end());
res.push_back(vector<int>());
vector<int> v;
generate(0, v, S);
return res;
}
res.push_back(v);
generate(i + 1, v, S);
v.pop_back();
//这 过
while(i < S.size() - 1 && S[i] == S[i + 1]) {
i++;
}
}
}
};
Subsets 106
LeetCode题
Permutation
Permutation这 backtracking
题 Combination 辙
对 给 组 DFS 层 层 历 这 section
们 对 leetcode 现 permutation问题进
.
Permutations
given a collection of numbers, return all posibile permutations.
For example, [1,2,3] have the following permutations: [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and
[3,2,1].
题 译: 给 组 这 组 变 给 .
题 :这 题 题 . Permutation 题
Combination Permutation bool类 组 进 记录哪
访问 哪 这样 导 现 Combination Permutation
.
题 : 这 问题 显 们 DFS,递归 对 组
为 节 Permutations,这 递归 组 历 这
样 另 问题 们 对 访问 这 们 们
bool类 组 记录哪 历 ( 过 标 对应). 对 Permutation进
访问 这 , 们 对应 bool 组 值 为true,访问结 们 为false.
时间 杂 : 这 题 Combination, 对 这 题 时间 杂 样 O(n!)
码 :
class Solution {
public:
vector<vector<int> > permute(vector<int> &num) {
vector<vector<int>> permutations;
if(num.size() == 0) //invalid corner case check
return permutations;
vector<int> curr;
vector<bool> isVisited(num.size(), false); //using this bool type array to check whether or n
backTracking(permutations,curr,isVisited,num);
return permutations;
}
Permutation 107
LeetCode题
{
if(curr.size() == num.size())
{
ret.push_back(curr);
return;
}
};
Permutations II
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example, [1,1,2] have the following unique permutations: [1,1,2], [1,2,1], and [2,1,1].
题 译: 给 组 这 组 们 这 组
Permutations, 说 permutation 现 . 诉读
.
题 :对 这 题 permutation, 题 Permutations
哪 为
1. 这 给 组 .
2. 组.
对 这两 Permutations 们 虑 样满 两 . 们
对 input 组进 时 permutation 这
这 们 pass 实这 sum combination 经 试 .
题 : 对 处 Permutation 样
时间 杂 : O(n!)
码 :
class Solution {
Permutation 108
LeetCode题
public:
vector<vector<int> > permuteUnique(vector<int> &num) {
vector<vector<int>> permutations;
if(num.size() == 0)
return permutations;
vector<int> curr;
vector<bool> isVisited(num.size(), false);
/* we need to sort the input array here because of this array
contains the duplication value, then we need to skip the duplication
value for the final result */
sort(num.begin(),num.end());
DFS(permutations,curr,num,isVisited);
return permutations;
}
Permutation 109
LeetCode题
Greedy
Greedy 110
LeetCode题
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.
这题 较简单 给 组 跃 们 动
贪 [2, 3, 1, 1, 4] 为 为2 们 1 1
3这 为3 1 们 跃3 4
规则 跃1 们 跃 减1 继
续 动 跃 0 还 败
码 :
class Solution {
public:
bool canJump(int A[], int n) {
if(n == 0) {
return true;
}
int v = A[0];
Jump Game II
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.
Your goal is to reach the last index in the minimum number of jumps.
The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3
steps to the last index.)
这题 题 们 跃 铁 终 们 贪
们维护两 变 达 远 p 达 远 q p 围 计 q
q设 为p 这 过 p达 终
class Solution {
public:
int jump(int A[], int n) {
int step = 0;
int cur = 0;
int next = 0;
int i = 0;
while(i < n){
if(cur >= n - 1) {
break;
}
return step;
}
};
Gas Station
There are N gas stations along a circular route, where the amount of gas at station i is gas[i].
You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next
station (i+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.
这题 哪 这 结
totalGas totalCost 设现 们 达 i 这时 还
为sum sum + gas[i] - cost[i] 0 们 i
铁 i+1 i+1
class Solution {
public:
int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
int sum = 0;
int total = 0;
int k = 0;
for(int i = 0; i < (int)gas.size(); i++) {
sum += gas[i] - cost[i];
// 0 i + 1
if(sum < 0) {
k = i + 1;
sum = 0;
}
total += gas[i] - cost[i];
}
if(total < 0) {
return -1;
} else {
return k;
}
}
};
Candy
There are N children standing in a line. Each child is assigned a rating value.
You are giving candies to these children subjected to the following requirements:
Each child must have at least one candy. Children with a higher rating get more candies than their
neighbors. What is the minimum candies you must give?
终 队领 时 们
这题 领 颗 级别 边
问 发
们 给 颗 设 i 级 i-1 i
i-1 们 i 级 i+1
时 i 时 i+1 i i+1
class Solution {
public:
int candy(vector<int> &ratings) {
vector<int> candys;
// 发 颗
candys.resize(ratings.size(), 1);
//这 环 证 边 级别 边
for(int i = 1; i < (int)ratings.size(); i++) {
if(ratings[i] > ratings[i - 1]) {
candys[i] = candys[i - 1] + 1;
}
}
//这 环 证 边 级别 边
for(int i = (int)ratings.size() - 2; i >= 0; i--) {
if(ratings[i] > ratings[i + 1] && candys[i] <= candys[i + 1]) {
candys[i] = candys[i + 1] + 1;
}
}
int n = 0;
for(int i = 0; i < (int)candys.size(); i++) {
n += candys[i];
}
return n;
}
};
Candy 114
LeetCode题
Word Break
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-
separated sequence of one or more dictionary words.
这题 给 词 这
设dp(i) 长 为i 别 dp :
class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict) {
int len = (int)s.size();
vector<bool> dp(len + 1, false);
dp[0] = true;
World Break II
Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each
word is a valid dictionary word.
For example, given s = "catsanddog", dict = ["cat", "cats", "and", "sand", "dog"].
这 题 题 们 这 题难 们 dp + dfs
dp 该 时 dp 过 记录 续dfs
们 dp[i][j] 为i 长 为j 态:
题 们 进 dp 时 处 1 2这两 为对 2 说
dp[i][j] 继续 说 们 1
class Solution {
public:
vector<vector<char> >dp;
vector<string> vals;
string val;
// dfs
if(dp[0][len] == 0) {
return vals;
}
dfs(s, 0);
return vals;
}
// 们 start + i 继续dfs
dfs(s, start + i);
val.erase(oldLen, string::npos);
}
}
}
};
Linked List
链 线 结构 链 删 O(1) 时间 杂 链 访问
这 给链 类问题带 烦 另 单 链 访问 驱节 这 链
难 链 类问题 链 创 删 查 础 实现
链
针
链 问题 针 义两 针 针 另 针 针
动 节 针 动 节 这 寻 链
链 让 针 动两 节 这样 针 达链 时 针刚 链
间
这 题 链 环 简单 题 们 两 针 两
时间 这两 针 铁 环
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head == NULL || head->next == NULL) {
return false;
}
return false;
}
};
紧 题 这题 环 还 这 环 节 这
n2
n6-----------n5
| |
n1--- n2---n3--- n4|
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(head == NULL || head->next == NULL) {
return NULL;
}
return NULL;
}
};
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
Notes:
The linked lists must retain their original structure after the function returns.
You may assume there are no cycles anywhere in the entire linked structure.
Your code should preferably run in O(n) time and use only O(1) memory.
这题 两 链 c1 这 题 简单
历A 结 A 节 连 B 头 c3 -> b1
两 针fast slow a1 环
环 记 c3 -> b1 给
环 则 题 c1 c3 -> b1
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA) {
return NULL;
} else if (!headB) {
return NULL;
}
ListNode* p = headA;
while(p->next) {
p = p->next;
}
// 两 链
p->next = headB;
ListNode* tail = p;
p = headA;
//fast slow 环
headB = headA;
while(headB->next && headB->next->next) {
headA = headA->next;
headB = headB->next->next;
if(headA == headB) {
break;
}
}
// 环 环
headA = p;
while(headA != headB) {
headA = headA->next;
headB = headB->next;
}
// 两 链
tail->next = NULL;
return headA;
}
};
For example,
这题 链 删 较简单 题 们
针 针时 则删 针
码 :
class Solution {
public:
ListNode *deleteDuplicates(ListNode *head) {
if(!head) {
return head;
}
return head;
}
};
For example,
这题 链 删 节 为 题 这
删 们 历 时 记录 prev节 处 删 节 节 连 问题
class Solution {
public:
ListNode *deleteDuplicates(ListNode *head) {
if(!head) {
return head;
}
//删 节
prev->next = n;
p = n;
}
}
return dummy.next;
}
};
这题 两 经 链 简单 题 码
class Solution {
public:
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
ListNode dummy(0);
ListNode* p = &dummy;
//这 处 还 载 节
if(l1) {
p->next = l1;
} else if(l2) {
p->next = l2;
}
return dummy.next;
}
};
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
if(lists.empty()) {
return NULL;
}
int n = lists.size();
while(n > 1) {
int k = (n + 1) / 2;
for(int i = 0; i < n / 2; i++) {
// i i + k 链 i
lists[i] = merge2List(lists[i], lists[i + k]);
}
// 环 处 k 链
n = k;
}
return lists[0];
}
if(n1) {
p->next = n1;
} else if(n2) {
p->next = n2;
}
return dummy.next;
}
};
return 1->4->3->2->5->NULL.
// p3
n = p2->next;
// p3 next 载 p2
p2->next = p3->next;
// p3 载 p1
p1->next = p3;
// p2 载 p3
p3->next = p2;
对 题 们 历 m - 1 node pm 驱节 历 处 载问题
class Solution {
public:
ListNode *reverseBetween(ListNode *head, int m, int n) {
if(!head) {
return head;
}
ListNode dummy(0);
dummy.next = head;
ListNode* p = &dummy;
for(int i = 1; i < m; i++) {
p = p->next;
}
//p 时 pm 驱节
ListNode* pm = p->next;
return dummy.next;
}
};
If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
这题 们 k 节 对 进 转 链 转 处
k 转 节 为这 节 组 驱节
ListNode dummy(0);
dummy.next = head;
ListNode* p = &dummy;
ListNode* prev = &dummy;
while(p) {
prev = p;
for(int i = 0; i < k; i++){
p = p->next;
if(!p) {
// 这 经 够k 转
return dummy.next;
}
}
p = reverse(prev, p->next);
}
return dummy.next;
}
while(p->next != end) {
ListNode* n = p->next;
p->next = n->next;
n->next = prev->next;
prev->next = n;
}
//这 们 节 为 组 驱节
return p;
}
For example, Given 1->2->3->4, you should return the list as 2->1->4->3.
Your algorithm should use only constant space. You may not modify the values in the list, only nodes
itself can be changed.
这题 历链 两两 换 较简单 题 们 换 驱节
码
class Solution {
public:
ListNode *swapPairs(ListNode *head) {
if(!head || !head->next) {
return head;
}
ListNode dummy(0);
ListNode* p = &dummy;
dummy.next = head;
return dummy.next;
}
};
Sort List
Sort a linked list in O(n log n) time using constant space complexity.
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(head == NULL || head->next == NULL) {
return head;
}
// 针 间
while(fast->next && fast->next->next) {
fast = fast->next->next;
slow = slow->next;
}
// 链 两
fast = slow->next;
slow->next = NULL;
// 两 别
ListNode* p1 = sortList(head);
ListNode* p2 = sortList(fast);
//
return merge(p1, p2);
}
ListNode dummy(0);
ListNode* p = &dummy;
p = p->next;
}
if(l1) {
p->next = l1;
} else if(l2){
p->next = l2;
}
return dummy.next;
}
};
这题 们 对链 进 设 链 n 节 n+1 节
历 n
class Solution {
public:
ListNode *insertionSortList(ListNode *head) {
if(head == NULL || head->next == NULL) {
return head;
}
ListNode dummy(0);
ListNode* p = &dummy;
ListNode* n = p->next;
p->next = cur;
cur = cur->next;
p->next->next = n;
}
return dummy.next;
}
};
Rotate List
Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
return 4->5->1->2->3->NULL.
这题 链 k 节 轮转 链
对 这题 们 历链 链 长 n 为k n 们 处 链
换 历n - k % n 节 这 k 2 们 历
链 结 连 1 历 5 - 2 % 5 节 环 节 链 头
class Solution {
public:
ListNode *rotateRight(ListNode *head, int k) {
if(!head || k == 0) {
return head;
}
int n = 1;
ListNode* p = head;
// 链 长
while(p->next) {
p = p->next;
n++;
}
k = n - k % n;
//连 环
p->next = head;
// 链 头 环
head = p->next;
p->next = NULL;
return head;
}
};
Reorder List
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
For example,
这题 较简单 实 链 两边 时 转
针 链
转
class Solution {
public:
void reorderList(ListNode *head) {
if(head == NULL || head->next == NULL) {
return;
}
// 针 链
while(fast->next != NULL && fast->next->next != NULL){
fast = fast->next->next;
slow = slow->next;
}
fast = slow->next;
slow->next = NULL;
// 转
ListNode dummy(0);
while(fast) {
ListNode* n = dummy.next;
dummy.next = fast;
ListNode* nn = fast->next;
fast->next = n;
fast = nn;
}
slow = head;
fast = dummy.next;
//
while(slow) {
if(fast != NULL) {
ListNode* n = slow->next;
slow->next = fast;
ListNode* nn = fast->next;
fast->next = n;
fast = nn;
slow = n;
} else {
break;
}
}
}
};
Partition List
Given a linked list and a value x, partition it such that all nodes less than x come before nodes
greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
return 1->2->2->4->3->5.
这题 们 链 进 节 值 x x
们 两 链 p1 p2 历 链 节 值 x 载 p1 则
p2 p2 载 p1
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
ListNode dummy1(0), dummy2(0);
ListNode* p1 = &dummy1;
ListNode* p2 = &dummy2;
ListNode* p = head;
while(p) {
if(p->val < x) {
p1->next = p;
p1 = p1->next;
} else {
p2->next = p;
p2 = p2->next;
}
p = p->next;
}
p2->next = NULL;
p1->next = dummy2.next;
return dummy1.next;
}
};
两 链 问题 处 进 较简单 码
class Solution {
public:
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
ListNode dummy(0);
ListNode* p = &dummy;
int cn = 0;
while(l1 || l2) {
int val = cn + (l1 ? l1->val : 0) + (l2 ? l2->val : 0);
cn = val / 10;
val = val % 10;
p->next = new ListNode(val);
p = p->next;
if(l1) {
l1 = l1->next;
}
if(l2) {
l2 = l2->next;
}
}
if(cn != 0) {
p->next = new ListNode(cn);
p = p->next;
}
return dummy.next;
}
};
这题 贝 带 random 针 链 random 链 节
对 链 们递归 贝 时 hash 记录 节 处
random问题
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
if(head == NULL) {
return NULL;
}
RandomListNode dummy(0);
RandomListNode* n = &dummy;
RandomListNode* h = head;
map<RandomListNode*, RandomListNode*> m;
while(h) {
RandomListNode* node = new RandomListNode(h->label);
n->next = node;
n = node;
node->random = h->random;
m[h] = node;
h = h->next;
}
h = dummy.next;
while(h) {
if(h->random != NULL) {
h->random = m[h->random];
}
h = h->next;
}
return dummy.next;
}
};
这题 实还 设 链
|------------|
| v
1 --> 2 --> 3 --> 4
节 1 random 3 们 过next 历链 贝节 节
|--------------------------|
| v
1 --> 1' --> 2 --> 2' --> 3 --> 3' --> 4 --> 4'
| ^
|-------------------|
为 们 简单 random 针 节 random 节 1
1' 3
|--------------------------|
| v
1 --> 1' --> 2 --> 2' --> 3 --> 3' --> 4 --> 4'
| ^
|-------------------------|
链 贝 链
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
if(head == NULL) {
return NULL;
}
// 历 节
RandomListNode* n = NULL;
RandomListNode* h = head;
while(h) {
RandomListNode* node = new RandomListNode(h->label);
node->random = h->random;
n = h->next;
h->next = node;
node->next = n;
h = n;
}
//调 random
h = head->next;
while(h) {
if(h->random != NULL) {
h->random = h->random->next;
}
if(!h->next) {
break;
}
h = h->next->next;
}
// 链
h = head;
RandomListNode dummy(0);
RandomListNode* p = &dummy;
while(h) {
n = h->next;
p->next = n;
p = n;
RandomListNode* nn = n->next;
h->next = n->next;
h = n->next;
}
return dummy.next;
}
};
Math
这 们 针对 leetcode 现 问题给 .这 问题 较 ,
.
Math 141
LeetCode题
Reverse Integer
Reverse Integer: Reverse digits of an integer.
题 :这 纯 问题 们 虑 corner case 说 这 0 话
们 这 . 简单 问题 码 :
class Solution {
public:
int reverse(int x) {
if(x == 0)
return x;
int ret = 0;
while(x!=0)
{
ret = ret*10 + x%10;
x = x/10;
}
return ret;
}
};
String
这 们 leetcode string 联 题 .
String 143
LeetCode题
Add Binary
Given two binary strings, return their sum (also a binary string).
题 译: 对 给 两 进 达 们 结
.
题 : 认为这 题 :
1. 对 .
2. 对 们应该 进 单 进 值.
3. 们还 虑两 长 样.
4. int 类 char类 转换.
时间 杂 : 实这 针对两 O(n) n 长 长 .
码 :
class Solution {
public:
string addBinary(string a, string b) {
int len1 = a.size();
int len2 = b.size();
if(len1 == 0)
return b;
if(len2 == 0)
return a;
string ret;
int carry = 0;
int index1 = len1-1;
int index2 = len2-1;
while(index1 >= 0)
{
int num = (a[index1]-'0')+carry;
carry = num/2;
num = num%2;
index1--;
ret.insert(ret.begin(),num+'0');
}
while(index2 >= 0)
{
int num = (b[index2]-'0')+carry;
carry = num/2;
num = num%2;
index2--;
ret.insert(ret.begin(),num+'0');
}
if(carry == 1)
ret.insert(ret.begin(),carry+'0');
return ret;
}
};
Basic Calculator II
Implement a basic calculator to evaluate a simple expression string. The expression string contains
only non-negative integers, +, -, *, / operators and empty spaces . The integer division
should truncate toward zero. You may assume that the given expression is always valid. Some
examples:
"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5
题 译 实现 简 计 对简单 达 值 达 负 + -
* / 运 给 达 eval
题 对 术 达 值 栈 实现 鉴 题 较简单 栈
实现 总 读 时 进 运 结
间变 减 结 终结
class Solution {
public:
int calculate(string s) {
int result = 0, inter_res = 0, num = 0;
char op = '+';
char ch;
for (int pos = s.find_first_not_of(' '); pos < s.size(); pos = s.find_first_not_of(
ch = s[pos];
if (ch >= '0' && ch <= '9') {
int num = ch - '0';
while (++pos < s.size() && s[pos] >= '0' && s[pos] <= '9')
num = num * 10 + s[pos] - '0';
switch (op) {
case '+':
inter_res += num;
break;
case '-':
inter_res -= num;
break;
case '*':
inter_res *= num;
break;
case '/':
inter_res /= num;
break;
}
}
else {
if (ch == '+' || ch == '-') {
result += inter_res;
inter_res = 0;
}
op = s[pos++];
}
}
return result + inter_res;
}
};