文章目录
- [面试题03. 数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof)
- [面试题04. 二维数组中的查找](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof)
- [面试题05. 替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/)
- [面试题06. 从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/)
- [面试题07. 重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/)
- [面试题08. 二叉树的下一个结点](https://blog.csdn.net/ft_sunshine/article/details/103139659)
- [面试题09. 用两个栈实现队列](https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/)
- [面试题10- I. 斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/)
- [面试题10- II. 青蛙跳台阶问题](https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/)
- [面试题11. 旋转数组的最小数字](https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/)
- [面试题12. 矩阵中的路径](https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/submissions/)
- [面试题13. 机器人的运动范围](https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/)
- [面试题14- I. 剪绳子](https://leetcode-cn.com/problems/jian-sheng-zi-lcof/)
- [面试题14- II. 剪绳子 II](https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/)
- [面试题15. 二进制中1的个数](https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/)
- [面试题16. 数值的整数次方](https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/)
- [面试题17. 打印从1到最大的n位数](https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/)
- [面试题18. 删除链表的节点](https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/)
- [面试题19. 正则表达式匹配](https://leetcode-cn.com/problems/zheng-ze-biao-da-shi-pi-pei-lcof/)
- [面试题20. 表示数值的字符串](https://leetcode-cn.com/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/)
- [面试题21. 调整数组顺序使奇数位于偶数前面](https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/)
- [面试题22. 链表中倒数第k个节点](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/)
- [面试题23. 链表中环的入口节点](https://leetcode-cn.com/problems/linked-list-cycle-ii/)
- [面试题24. 反转链表](https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/)
- [面试题25. 合并两个排序的链表](https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/)
- [面试题26. 树的子结构](https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/)
- [面试题27. 二叉树的镜像](https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/)
- [面试题28. 对称的二叉树](https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/)
- [面试题29. 顺时针打印矩阵](https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/)
- [面试题30. 包含min函数的栈](https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/)
- [面试题31. 栈的压入、弹出序列](https://leetcode-cn.com/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/)
- [面试题32 - I. 从上到下打印二叉树](https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/)
- [面试题32 - II. 从上到下打印二叉树 II](https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/)
- [面试题32 - III. 从上到下打印二叉树 III](https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/)
- [面试题33. 二叉搜索树的后序遍历序列](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/s)
- [面试题34. 二叉树中和为某一值的路径](https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/)
- [面试题35. 复杂链表的复制](https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/)
- [面试题36. 二叉搜索树与双向链表](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/)
- [面试题37. 序列化二叉树](https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/)
- [面试题38. 字符串的排列](https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/)
- [面试题39. 数组中出现次数超过一半的数字](https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/)
- [面试题40. 最小的k个数](https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/)
- [面试题41. 数据流中的中位数](https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/)
- [面试题42. 连续子数组的最大和](https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/)
- [面试题43. 1~n整数中1出现的次数](https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/)
- [面试题44. 数字序列中某一位的数字](https://leetcode-cn.com/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/)
- [面试题45. 把数组排成最小的数](https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/)
- [面试题46. 把数字翻译成字符串](https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/)
- [面试题47. 礼物的最大价值](https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/)
- [面试题48. 最长不含重复字符的子字符串](https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/)
- [面试题49. 丑数](https://leetcode-cn.com/problems/chou-shu-lcof/)
- [面试题50. 第一个只出现一次的字符](https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/)
- [面试题51. 数组中的逆序对](https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/)
- [面试题52. 两个链表的第一个公共节点](https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/)
- [面试题53 - I. 在排序数组中查找数字 I](https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/)
- [面试题53 - II. 0~n-1中缺失的数字](https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof/)
- [面试题54. 二叉搜索树的第k大节点](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/)
- [面试题55 - I. 二叉树的深度](https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/)
- [面试题55 - II. 平衡二叉树](https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/)
- [面试题56 - I. 数组中数字出现的次数](https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/)
- [面试题56 - II. 数组中数字出现的次数 II](https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/)
- [面试题57 - I. 和为s的两个数字](https://leetcode-cn.com/problems/he-wei-sde-liang-ge-shu-zi-lcof/)
- [面试题57 - II. 和为s的连续正数序列](https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/)
- [面试题58 - I. 翻转单词顺序](https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/)
- [面试题58 - II. 左旋转字符串](https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/)
- [面试题59 - I. 滑动窗口的最大值](https://leetcode-cn.com/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof/)
- [面试题59 - II. 队列的最大值](https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/)
- [面试题60. n个骰子的点数](https://leetcode-cn.com/problems/nge-tou-zi-de-dian-shu-lcof/)
- [面试题61. 扑克牌中的顺子](https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/)
- [面试题62. 圆圈中最后剩下的数字](https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/)
- [面试题63. 股票的最大利润](https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof/)
- [面试题64. 求1+2+…+n](https://leetcode-cn.com/problems/qiu-12n-lcof/)
- [面试题65. 不用加减乘除做加法](https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/)
- [面试题66. 构建乘积数组](https://leetcode-cn.com/problems/gou-jian-cheng-ji-shu-zu-lcof/)
- [面试题67. 把字符串转换成整数](https://leetcode-cn.com/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof/)
- [面试题68 - I. 二叉搜索树的最近公共祖先](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/)
- [面试题68 - II. 二叉树的最近公共祖先](https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/)
下面只给出答案,具体题目请参考: LeetCode专题 ——《剑指offer》
面试题03. 数组中重复的数字
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
int length = nums.size();
if(length == 0)
return false;
for(int i = 0; i < length; i++){
if(i == nums[i])
continue;
while(i != nums[i]){
if(nums[i] == nums[nums[i]])
return nums[i];
else
swap(nums[i], nums[nums[i]]);
}
}
return -1;
}
};
面试题04. 二维数组中的查找
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int> > matrix, int target) {
if(matrix.size() == 0 || matrix[0].size() == 0)
return false;
int rows = matrix.size();
int cols = matrix[0].size();
int row = 0;
int col = cols - 1;
while(row < rows && col >= 0){
if(matrix[row][col] == target)
return true;
else if(matrix[row][col] < target)
row++;
else
col--;
}
return false;
}
};
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int> > matrix, int target) {
for(int i = 0; i < matrix.size(); i++){
int low = 0;
int high = matrix[i].size() - 1;
while(low <= high){
int mid = (low + high) / 2;
if(target > matrix[i][mid])
low = mid + 1;
else if(target < matrix[i][mid])
high = mid - 1;
else
return true;
}
}
return false;
}
};
面试题05. 替换空格
class Solution {
public:
string replaceSpace(string str) {
int length = str.size();
if(length <= 0)
return "";
int numOfBlank = 0;
for(int i = 0; i < length; i++){
if(str[i] == ' ')
numOfBlank++;
}
int newLength = length + 2 * numOfBlank;
string res(newLength, ' ');
int indexOfOriginalStr = length - 1;
int indexOfNewStr = newLength - 1;
while(indexOfOriginalStr >=0 && indexOfNewStr >=0){
if(str[indexOfOriginalStr] == ' '){
res[indexOfNewStr--] = '0';
res[indexOfNewStr--] = '2';
res[indexOfNewStr--] = '%';
indexOfOriginalStr--;
}else{
res[indexOfNewStr--] = str[indexOfOriginalStr--];
}
}
return res;
}
};
面试题06. 从尾到头打印链表
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
reversePrintRecursively(head);
return myVector;
}
void reversePrintRecursively(ListNode* head){
if(head != nullptr){
reversePrint(head->next);
myVector.push_back(head->val);
}
}
private:
vector<int> myVector;
};
面试题07. 重建二叉树
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.size() <= 0 || inorder.size() <= 0 || preorder.size() != inorder.size()){
return nullptr;
}
int length = preorder.size();
return reConstructRecursively(preorder, 0, length - 1, inorder, 0, length - 1);
}
TreeNode* reConstructRecursively(vector<int> &preorder, int preStart, int preEnd,
vector<int> &inorder, int inStart, int inEnd){
int rootVal = preorder[preStart];
TreeNode* root = new TreeNode(rootVal);
root->left = root->right = nullptr;
if(preStart == preEnd && inStart == inEnd && preorder[preStart] == inorder[inStart])
return root;
int inRoot = inStart;
for(; inRoot <= inEnd; inRoot++){
if(inorder[inRoot] == rootVal)
break;
}
int leftLength = inRoot - inStart;
if(leftLength > 0){
root->left = reConstructRecursively(preorder, preStart+1, preStart+leftLength, inorder, inStart, inRoot-1);
}
if(inEnd - inRoot > 0){
root->right = reConstructRecursively(preorder, preStart+leftLength+1, preEnd, inorder, inRoot+1, inEnd);
}
return root;
}
};
面试题08. 二叉树的下一个结点
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(pNode == nullptr)
return nullptr;
TreeLinkNode* pNextNode = nullptr;
if(pNode->right != nullptr){
TreeLinkNode* pRightNode = pNode->right;
while(pRightNode->left != nullptr)
pRightNode = pRightNode->left;
pNextNode = pRightNode;
return pNextNode;
}
TreeLinkNode* pParent = pNode->next;
while(pParent != nullptr){
if(pParent->left == pNode){
pNextNode = pParent;
break;
}else if(pParent->right == pNode){
pNode = pParent;
pParent = pParent->next;
}
}
return pNextNode;
}
};
面试题09. 用两个栈实现队列
int g_invalidInput = false;
class CQueue{
public:
CQueue() {
}
void appendTail(int value){
stack1.push(value);
}
int deleteHead(){
if(stack2.empty()){
while(!stack1.empty()){
stack2.push(stack1.top());
stack1.pop();
}
}
if(!stack2.empty()){
int res = stack2.top();
stack2.pop();
return res;
}
g_invalidInput = true;
return -1;
}
private:
stack<int> stack1;
stack<int> stack2;
};
bool g_invalidInput = false;
class MyStack {
public:
MyStack() {
}
void push(int x) {
if(!q1.empty())
q1.push(x);
else
q2.push(x);
}
int pop() {
if(!q1.empty()){
int num = q1.size();
while(num != 1){
q2.push(q1.front());
q1.pop();
num--;
}
int res = q1.front();
q1.pop();
return res;
}else{
int num = q2.size();
while(num != 1){
q1.push(q2.front());
q2.pop();
num--;
}
int res = q2.front();
q2.pop();
return res;
}
g_invalidInput = true;
return -1;
}
int top() {
if(!q1.empty()){
return q1.back();
}else{
return q2.back();
}
g_invalidInput = true;
return -1;
}
bool empty() {
if(q1.empty() && q2.empty())
return true;
else
return false;
}
private:
queue<int> q1, q2;
};
面试题10- I. 斐波那契数列
typedef long long LL;
class Solution {
public:
int fib(int n) {
if(n == 0)
return 0;
if(n == 1)
return 1;
LL curMinus1 = 1;
LL curMinus2 = 0;
LL res = 0;
for(int i = 2; i <= n; i++){
res = (curMinus1 + curMinus2) % 1000000007;
curMinus2 = curMinus1;
curMinus1 = res;
}
return res;
}
};
面试题10- II. 青蛙跳台阶问题
typedef long long LL;
class Solution {
public:
int numWays(int n) {
if(n == 0)
return 1;
if(n == 1)
return 1;
LL curMinus1 = 1;
LL curMinus2 = 1;
LL res = 0;
for(int i = 2; i <= n; i++){
res = (curMinus1 + curMinus2) % 1000000007;
curMinus2 = curMinus1;
curMinus1 = res;
}
return res;
}
};
面试题11. 旋转数组的最小数字
class Solution {
public:
int minArray(vector<int> rotateArray) {
int length = rotateArray.size();
if(length == 0)
return 0;
int low = 0, high = length-1;
int mid = low;
while(rotateArray[low] >= rotateArray[high]){
if(high - low == 1){
mid = high;
break;
}
mid = (low + high) >> 1;
if(rotateArray[low] == rotateArray[mid] && rotateArray[mid] == rotateArray[high]){
return minInArray(rotateArray, low, high);
}
if(rotateArray[mid] >= rotateArray[low])
low = mid;
else
high = mid;
}
return rotateArray[mid];
}
int minInArray(vector<int> rotateArray, int low, int high){
int _Min = 0x7FFFFFFF;
for(int i=0; i<rotateArray.size(); i++){
if(rotateArray[i] < _Min)
_Min = rotateArray[i];
}
return _Min;
}
};
面试题12. 矩阵中的路径
class Solution {
public:
bool exist(vector<vector<char>>& matrix, string str){
int rows = matrix.size();
if(rows == 0)
return false;
int cols = matrix[0].size();
if(cols == 0)
return false;
int strLength = str.length();
if(strLength == 0)
return false;
bool visited[rows * cols];
memset(visited, 0, sizeof(visited));
int strPosition = 0;
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
if(hashPathRecusively(matrix, rows, cols, i, j, str, strPosition, visited)){
return true;
}
}
}
return false;
}
bool hashPathRecusively(vector<vector<char>> &matrix, int rows, int cols, int row, int col,
string &str, int strPosition, bool* visited){
if(strPosition == str.length())
return true;
bool hasPath = false;
if(row >= 0 && row < rows && col >= 0 && col < cols &&
matrix[row][col] == str[strPosition] && !visited[row*cols + col]){
strPosition++;
visited[row*cols + col] = true;
hasPath = hashPathRecusively(matrix, rows, cols, row-1, col, str, strPosition, visited) ||
hashPathRecusively(matrix, rows, cols, row+1, col, str, strPosition, visited) ||
hashPathRecusively(matrix, rows, cols, row, col-1, str, strPosition, visited) ||
hashPathRecusively(matrix, rows, cols, row, col+1, str, strPosition, visited);
if(!hasPath){
strPosition--;
visited[row*cols + col] = false;
}
}
return hasPath;
}
};
面试题13. 机器人的运动范围
class Solution {
public:
int movingCount(int rows, int cols, int threshold){
if(rows <= 0 || cols <= 0 || threshold < 0)
return 0;
bool visited[rows * cols];
memset(visited, 0, rows*cols);
return arriveNumOfGrid(threshold, rows, cols, 0, 0, visited);
}
int arriveNumOfGrid(int threshold, int rows, int cols, int row, int col, bool* visited){
int mSum = 0;
if(row >= 0 && row < rows && col >= 0 && col < cols && sumOfTwoNum(row, col) <= threshold
&& !visited[row*cols + col]){
visited[row*cols + col] = true;
mSum = 1 + arriveNumOfGrid(threshold, rows, cols, row-1, col, visited)
+ arriveNumOfGrid(threshold, rows, cols, row+1, col, visited)
+ arriveNumOfGrid(threshold, rows, cols, row, col-1, visited)
+ arriveNumOfGrid(threshold, rows, cols, row, col+1, visited);
}
return mSum;
}
int sumOfTwoNum(int a, int b){
return sumOfOneNum(a) + sumOfOneNum(b);
}
int sumOfOneNum(int n){
int _sum = 0;
while(n){
_sum += n%10;
n /= 10;
}
return _sum;
}
};
面试题14- I. 剪绳子
class Solution {
public:
int cuttingRope(int number) {
if(number == 0)
return 0;
if(number == 1)
return 1;
if(number == 2)
return 1;
if(number == 3)
return 2;
int res[number + 1];
for(int i = 0; i <= 3; i++)
res[i] = i;
for(int length = 4; length <= number; length++){
int iMax = INT_MIN;
for(int left = 1; left <= length/2; left++){
int right = length - left;
iMax = max(iMax, res[left] * res[right]);
}
res[length] = iMax;
}
return res[number];
}
};
面试题14- II. 剪绳子 II
typedef long long LL;
class Solution {
public:
int cuttingRope(int n) {
if(n == 0)
return 0;
if(n == 1)
return 1;
if (n == 2)
return 1;
if (n == 3)
return 2;
int remainder = n % 3;
LL res = 1;
for(int i = 0; i < n / 3 - 1; i++) {
res = (res * 3) % 1000000007;
}
if (remainder == 0) {
res = (res * 3) % 1000000007;
} else if (remainder == 1) {
res = (res * 4) % 1000000007;
} else if(remainder == 2){
res = (res * 6) % 1000000007;
}
return (int)res;
}
};
面试题15. 二进制中1的个数
class Solution {
public:
int hammingWeight(uint32_t n) {
int sum = 0;
while(n){
n = (n-1)&n;
sum++;
}
return sum;
}
};
面试题16. 数值的整数次方
class Solution {
public:
double myPow(double x, int n) {
if(doubleEqualTo0(x) && n < 0)
return 0;
if(n == 0)
return 1;
if(n == 1)
return x;
if(n == -1)
return 1/x;
double half = myPow(x, n/2);
double rest = myPow(x, n%2);
return half * half * rest;
}
bool doubleEqualTo0(double a){
if(a>-0.0000001 && a < 0.0000001)
return true;
return false;
}
};
面试题17. 打印从1到最大的n位数
class Solution {
public:
vector<int> printNumbers(int n) {
vector<int> res;
int i = 1;
int imax = pow(10,n);
while(i < imax){
res.push_back(i++);
}
return res;
}
};
class Solution {
public:
vector<int> printNumbers(int n) {
string temp(n, '0');
printNumbersRecursively(n, temp, 0);
}
void printNumbersRecursively(int n, string temp, int index){
if(index == n){
int num = stoi(temp);
if(num != 0)
res.push_back(stoi(temp));
return;
}
for(int i = 0; i <= 9; i++){
temp[index] = i + '0';
printNumbersRecursively(n, temp, index + 1);
}
}
private:
vector<int> res;
};
面试题18. 删除链表的节点
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(-1);
ListNode* pNode = dummyHead;
dummyHead->next = head;
while(pNode && pNode->next && pNode->next->val != val)
pNode = pNode->next;
pNode->next = pNode->next->next;
return dummyHead->next;
}
};
class Solution {
public:
ListNode* deleteDuplicates(ListNode* pHead)
{
if(pHead == nullptr)
return nullptr;
ListNode* dummyHead = new ListNode(-1);
dummyHead->next = pHead;
ListNode* pPre = dummyHead;
ListNode* pNode = dummyHead->next;
while(pNode != nullptr){
ListNode* pNext = pNode -> next;
bool toBeDeleted = false;
if(pNext != nullptr && pNode->val == pNext->val)
toBeDeleted = true;
if(!toBeDeleted){
pPre = pNode;
pNode = pNext;
}else{
int duplication = pNode->val;
ListNode* deleteNode = pNode;
while(deleteNode->val == duplication){
pNext = deleteNode->next;
delete deleteNode;
deleteNode = pNext;
if(pNext == nullptr)
break;
}
pPre->next = pNext;
pNode = pNext;
}
}
return dummyHead->next;
}
};
面试题19. 正则表达式匹配
class Solution {
public:
bool isMatch(string str, string pattern)
{
if (str.length() == 0 && pattern.length() == 0)
return true;
if (pattern.length() == 0)
return false;
return matchRecursively(str, pattern, 0, 0);
}
bool matchRecursively(string &str, string &pattern, int indexOfStr, int indexOfPattern) {
if (indexOfStr == str.length() && indexOfPattern == pattern.length())
return true;
if (indexOfPattern == pattern.length())
return false;
if (indexOfPattern < pattern.size()-1 && pattern[indexOfPattern + 1] == '*') {
if (str[indexOfStr] == pattern[indexOfPattern] || (indexOfStr != str.length() && pattern[indexOfPattern] == '.'))
return matchRecursively(str, pattern, indexOfStr + 1, indexOfPattern) ||
matchRecursively(str, pattern, indexOfStr, indexOfPattern+2);
else
return matchRecursively(str, pattern, indexOfStr, indexOfPattern+2);
}else {
if (str[indexOfStr] == pattern[indexOfPattern] || (indexOfStr != str.length() && pattern[indexOfPattern] == '.'))
return matchRecursively(str, pattern, indexOfStr + 1, indexOfPattern + 1);
else
return false;
}
}
};
class Solution {
public:
bool isMatch(string s, string p){
int m = s.size();
int n = p.size();
if(m == 0 && n == 0)
return true;
if(n == 0)
return false;
bool dp[m + 1][n + 1] = {0};
memset(dp, 0, sizeof(dp));
dp[0][0] = true;
for(int j = 2; j <= n; j++)
dp[0][j] = dp[0][j-2] && p[j-1] == '*';
for(int i = 1; i <= m; i++){
for(int j = 1; j <= n; j++){
if(s[i-1] == p[j-1] || p[j-1] == '.'){
dp[i][j] = dp[i-1][j-1];
}else if(p[j-1] == '*'){
if(s[i-1] == p[j-2] || p[j-2] == '.')
dp[i][j] = dp[i][j-2] || dp[i-1][j];
else
dp[i][j] = dp[i][j-2];
}
}
}
return dp[m][n];
}
};
面试题20. 表示数值的字符串
class Solution {
public:
bool isNumber(string str){
int low = 0, high = str.size() - 1;
while(low <= high && str[low] == ' ') low++;
while(low <= high && str[high] == ' ') high--;
if(high < low)
return false;
str = str.substr(low, high - low + 1);
length = str.size();
if(length == 0)
return false;
int indexOfStr = 0;
bool res = isInteger(str, indexOfStr);
if(indexOfStr < length && str[indexOfStr] == '.'){
indexOfStr++;
res = isUnsignedInteger(str, indexOfStr) || res;
}
if(indexOfStr < length && (str[indexOfStr] == 'e' || str[indexOfStr] == 'E')){
indexOfStr++;
res = res && isInteger(str, indexOfStr);
}
return res && indexOfStr == length;
}
bool isInteger(string str, int &indexOfStr){
if(indexOfStr < length && (str[indexOfStr] == '+' || str[indexOfStr] == '-'))
indexOfStr++;
return isUnsignedInteger(str, indexOfStr);
}
bool isUnsignedInteger(string str, int &indexOfStr){
if(indexOfStr >= length || str[indexOfStr] < '0' || str[indexOfStr] > '9')
return false;
while(indexOfStr < length && str[indexOfStr] >= '0' && str[indexOfStr] <= '9')
indexOfStr++;
return true;
}
private:
int length;
};
面试题21. 调整数组顺序使奇数位于偶数前面
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
int length = nums.size();
if(length <= 1)
return nums;
int left = 0, right = length - 1;
while(left < right){
while(left < right && nums[right] % 2 == 0)
right--;
while(left < right && nums[left] % 2 == 1)
left++;
if(left < right)
swap(nums[left], nums[right]);
}
return nums;
}
};
面试题22. 链表中倒数第k个节点
class Solution {
public:
ListNode* getKthFromEnd(ListNode* pListHead, int k) {
if(pListHead == nullptr || k <= 0)
return nullptr;
int length = 0;
ListNode* pNode = pListHead;
while(pNode != nullptr){
length++;
pNode = pNode->next;
}
if(k > length)
return nullptr;
ListNode* pQuickNode = pListHead;
ListNode* pSlowNode = pListHead;
for(int i = 1; i <= k-1; i++){
pQuickNode = pQuickNode->next;
}
while(pQuickNode->next != nullptr){
pSlowNode = pSlowNode->next;
pQuickNode = pQuickNode->next;
}
return pSlowNode;
}
};
面试题23. 链表中环的入口节点
class Solution {
public:
ListNode* detectCycle(ListNode* pHead){
if(pHead == nullptr)
return nullptr;
ListNode* pNodeInLoop = nullptr;
if(!hasLoop(pHead, &pNodeInLoop))
return nullptr;
ListNode* pNode = pNodeInLoop->next;
int numOfLoop = 1;
while(pNode != pNodeInLoop){
numOfLoop++;
pNode = pNode->next;
}
ListNode* pSlowNode = pHead;
ListNode* pQuickNode = pHead;
for(int i = 1; i <= numOfLoop; i++)
pQuickNode = pQuickNode->next;
while(pSlowNode != pQuickNode){
pSlowNode = pSlowNode->next;
pQuickNode = pQuickNode->next;
}
return pQuickNode;
}
bool hasLoop(ListNode* pHead, ListNode** pNodeInLoop){
ListNode* pSlowNode = pHead;
ListNode* pQuickNode = pHead->next;
while(pSlowNode != nullptr && pQuickNode != nullptr){
if(pSlowNode == pQuickNode){
*pNodeInLoop = pSlowNode;
return true;
}
pSlowNode = pSlowNode->next;
pQuickNode = pQuickNode->next;
if(pQuickNode != nullptr)
pQuickNode = pQuickNode->next;
}
return false;
}
};
面试题24. 反转链表
class Solution {
public:
ListNode* reverseList(ListNode* pHead) {
if(pHead == nullptr)
return nullptr;
ListNode* pPre = nullptr;
ListNode* pNode = pHead;
while(pNode != nullptr){
ListNode* pNext = pNode->next;
pNode->next = pPre;
pPre = pNode;
pNode = pNext;
}
return pPre;
}
};
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL) return head;
ListNode* p = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return p;
}
};
面试题25. 合并两个排序的链表
class Solution {
public:
ListNode* mergeTwoLists(ListNode* pHead1, ListNode* pHead2)
{
ListNode* pDummy = new ListNode(-1);
ListNode* pNode = pDummy;
while(pHead1 != nullptr && pHead2 != nullptr){
if(pHead1->val < pHead2->val){
pNode->next = pHead1;
pHead1 = pHead1->next;
}else{
pNode->next = pHead2;
pHead2 = pHead2->next;
}
pNode = pNode->next;
}
pNode->next = pHead1 == nullptr? pHead2: pHead1;
return pDummy->next;
}
};
class Solution {
public:
ListNode* mergeTwoLists(ListNode* pHead1, ListNode* pHead2)
{
if(pHead1 == nullptr && pHead2 == nullptr)
return nullptr;
ListNode* pHead = mergeRecursively(pHead1, pHead2);
return pHead;
}
ListNode* mergeRecursively(ListNode* pHead1, ListNode* pHead2){
if(pHead1 == nullptr)
return pHead2;
if(pHead2 == nullptr)
return pHead1;
ListNode* pHead = nullptr;
if(pHead1->val <= pHead2->val){
pHead = pHead1;
pHead->next = mergeRecursively(pHead1->next, pHead2);
}else{
pHead = pHead2;
pHead->next = mergeRecursively(pHead1, pHead2->next);
}
return pHead;
}
};
面试题26. 树的子结构
class Solution {
public:
bool isSubStructure(TreeNode* pRoot1, TreeNode* pRoot2)
{
if(pRoot1 == nullptr || pRoot2 == nullptr)
return false;
bool res = false;
if(pRoot1->val == pRoot2->val)
res = hasSubTreeRecusively(pRoot1, pRoot2);
if(!res)
res = isSubStructure(pRoot1->left, pRoot2);
if(!res)
res = isSubStructure(pRoot1->right, pRoot2);
return res;
}
bool hasSubTreeRecusively(TreeNode* pRoot1, TreeNode* pRoot2){
if(pRoot2 == nullptr)
return true;
if(pRoot1 == nullptr)
return false;
if(pRoot1->val != pRoot2->val)
return false;
return hasSubTreeRecusively(pRoot1->left, pRoot2->left) &&
hasSubTreeRecusively(pRoot1->right, pRoot2->right);
}
};
面试题27. 二叉树的镜像
class Solution {
public:
TreeNode* mirrorTree(TreeNode *pRoot) {
if(pRoot != nullptr){
TreeNode* pTemp = pRoot->left;
pRoot->left = pRoot->right;
pRoot->right = pTemp;
mirrorTree(pRoot->left);
mirrorTree(pRoot->right);
}
return pRoot;
}
};
面试题28. 对称的二叉树
class Solution {
public:
bool isSymmetric(TreeNode* pRoot)
{
if(pRoot == nullptr)
return true;
bool res = false;
res = isSymmetricalRecursively(pRoot, pRoot);
return res;
}
bool isSymmetricalRecursively(TreeNode* pRoot1, TreeNode* pRoot2){
if(pRoot1 == nullptr && pRoot2 == nullptr)
return true;
if(pRoot1 == nullptr || pRoot2 == nullptr)
return false;
if(pRoot1->val != pRoot2->val)
return false;
return isSymmetricalRecursively(pRoot1->left, pRoot2->right) &&
isSymmetricalRecursively(pRoot1->right, pRoot2->left);
}
};
面试题29. 顺时针打印矩阵
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int rows = matrix.size();
int cols = 0;
if(rows != 0)
cols = matrix[0].size();
vector<int> clockwise;
if(rows == 0 || cols == 0)
return clockwise;
for(int start = 0; start*2 < rows && start*2 < cols; start++){
printMatrixClockwise(matrix, rows, cols, start, clockwise);
}
return clockwise;
}
void printMatrixClockwise(vector<vector<int> > matrix, int rows, int cols, int start, vector<int> &clockwise){
int endX = cols - 1 - start;
int endY = rows - 1 - start;
for(int j = start; j <= endX; j++){
clockwise.push_back(matrix[start][j]);
}
if(endY-start > 0){
for(int i = start+1; i <= endY; i++){
clockwise.push_back(matrix[i][endX]);
}
}
if(endX-start > 0 && endY-start > 0){
for(int j = endX-1; j>=start; j--){
clockwise.push_back(matrix[endY][j]);
}
}
if(endX-start > 0 && endY-start > 1){
for(int i = endY-1; i > start; i--){
clockwise.push_back(matrix[i][start]);
}
}
}
};
面试题30. 包含min函数的栈
int g_invalidInput = false;
class MinStack {
public:
MinStack() {
}
void push(int value) {
data.push(value);
if(minInData.empty() || value < minInData.top())
minInData.push(value);
else
minInData.push(minInData.top());
}
void pop() {
if(!data.empty() && !minInData.empty()){
data.pop();
minInData.pop();
}
}
int top() {
if(!data.empty())
return data.top();
g_invalidInput = true;
return -1;
}
int min() {
if(!minInData.empty())
return minInData.top();
g_invalidInput = true;
return -1;
}
private:
stack<int> data;
stack<int> minInData;
};
面试题31. 栈的压入、弹出序列
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
if(pushed.size() == 0 && popped.size() == 0)
return true;
stack<int> s;
int popIndex = 0;
for(int i = 0; i < pushed.size(); i++){
s.push(pushed[i]);
while(!s.empty() && s.top() == popped[popIndex]){
s.pop();
popIndex++;
}
}
return s.empty();
}
};
面试题32 - I. 从上到下打印二叉树
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
vector<int> res;
if(root == nullptr)
return res;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
TreeNode* node = q.front();
q.pop();
res.push_back(node->val);
if(node->left)
q.push(node->left);
if(node->right)
q.push(node->right);
}
return res;
}
};
面试题32 - II. 从上到下打印二叉树 II
class Solution {
public:
vector<vector<int> > levelOrder(TreeNode* pRoot) {
vector<vector<int> > res;
if(pRoot == nullptr)
return res;
queue<TreeNode*> q;
q.push(pRoot);
while(!q.empty()){
int num = q.size();
vector<int> temp;
while(num--){
TreeNode* pNode = q.front(); q.pop();
temp.push_back(pNode->val);
if(pNode->left)
q.push(pNode->left);
if(pNode->right)
q.push(pNode->right);
}
res.push_back(temp);
}
return res;
}
};
面试题32 - III. 从上到下打印二叉树 III
class Solution {
public:
vector<vector<int> > levelOrder(TreeNode* pRoot) {
vector<vector<int> > res;
if(pRoot == nullptr)
return res;
stack<TreeNode*> mStack[2];
vector<int> mVector;
int flag = 0;
mStack[flag].push(pRoot);
while(!mStack[0].empty() || !mStack[1].empty()){
if(flag == 0){
while(!mStack[0].empty()){
TreeNode* node = mStack[0].top();
mVector.push_back(node->val);
mStack[0].pop();
if(node->left)
mStack[1].push(node->left);
if(node->right)
mStack[1].push(node->right);
}
res.push_back(mVector);
mVector.clear();
flag = 1;
}else if(flag == 1){
while(!mStack[1].empty()){
TreeNode* node = mStack[1].top();
mVector.push_back(node->val);
mStack[1].pop();
if(node->right)
mStack[0].push(node->right);
if(node->left)
mStack[0].push(node->left);
}
res.push_back(mVector);
mVector.clear();
flag = 0;
}
}
return res;
}
};
面试题33. 二叉搜索树的后序遍历序列
class Solution {
public:
bool verifyPostorder(vector<int> &sequence) {
int length = sequence.size();
if(length == 0)
return true;
bool res = false;
res = VerifySquenceOfBSTRecursively(sequence, 0, length-1);
return res;
}
bool VerifySquenceOfBSTRecursively(vector<int> sequence, int indexOfStart, int indexOfEnd){
int lastNum = sequence[indexOfEnd];
int i;
for(i = indexOfStart; i <= indexOfEnd-1; i++){
if(sequence[i] > lastNum)
break;
}
int j = i;
for(; j <= indexOfEnd-1; j++){
if(sequence[j] < lastNum)
return false;
}
int lengthOfLeft = i - indexOfStart;
int lengthOfRight = indexOfEnd - i;
bool left = false;
bool right = false;
if(lengthOfLeft == 0)
left = true;
else
left = VerifySquenceOfBSTRecursively(sequence, indexOfStart, i-1);
if(lengthOfRight == 0)
right = true;
else
right = VerifySquenceOfBSTRecursively(sequence, i, indexOfEnd-1);
return left && right;
}
};
面试题34. 二叉树中和为某一值的路径
class Solution {
public:
vector<vector<int> > pathSum(TreeNode* root, int expectNumber) {
if(root == nullptr)
return res;
vector<TreeNode*> path;
int currentSum = 0;
getPathRecursively(root, expectNumber, path, currentSum);
return res;
}
void getPathRecursively(TreeNode* root, int expectNumber, vector<TreeNode*> &path, int currentSum){
if(root != nullptr){
currentSum += root->val;
path.push_back(root);
bool isLeaf = root->left == nullptr && root->right == nullptr;
if(isLeaf && currentSum == expectNumber){
vector<int> temp;
for(auto iter = path.begin(); iter < path.end(); iter++)
temp.push_back((*iter)->val);
res.push_back(temp);
}
if(root->left){
getPathRecursively(root->left, expectNumber, path, currentSum);
}
if(root->right){
getPathRecursively(root->right, expectNumber, path, currentSum);
}
currentSum -= root->val;
path.pop_back();
}
}
private:
vector<vector<int> > res;
};
面试题35. 复杂链表的复制
class Solution {
public:
Node* copyRandomList(Node* pHead)
{
if(pHead == nullptr)
return nullptr;
Node* pNode = pHead;
while(pNode != nullptr){
Node* pCloneNode = new Node(pNode->val, nullptr, nullptr);
pCloneNode->next = pNode->next;
pNode->next = pCloneNode;
pNode = pCloneNode->next;
}
pNode = pHead;
while(pNode != nullptr){
Node* pCloneNode = pNode->next;
if(pNode->random != nullptr)
pCloneNode->random = pNode->random->next;
pNode = pCloneNode->next;
}
pNode = pHead;
Node* pCloneHead = pHead->next;
while(pNode != nullptr){
Node* pCloneNode = pNode->next;
pNode->next = pCloneNode->next;
pNode = pNode->next;
if(pNode == nullptr)
break;
pCloneNode->next = pNode->next;
}
return pCloneHead;
}
};
class Solution {
public:
Node* copyRandomList(Node* head) {
if (head == nullptr) {
return head;
}
Node *cur = head;
unordered_map<Node*, Node*> ump;
while (cur != nullptr) {
Node *copy = new Node(cur->val);
ump[cur] = copy;
cur = cur->next;
}
cur = head;
while (cur != nullptr) {
ump[cur]->next = ump[cur->next];
ump[cur]->random = ump[cur->random];
cur = cur->next;
}
return ump[head];
}
};
面试题36. 二叉搜索树与双向链表
class Solution {
public:
Node* treeToDoublyList(Node* pTreeRoot)
{
if(pTreeRoot == nullptr)
return nullptr;
Node* pFirstNodeInList = pTreeRoot;
while(pFirstNodeInList->left != nullptr)
pFirstNodeInList = pFirstNodeInList->left;
Node* pLastNodeInList = nullptr;
convertTreeRecursively(pTreeRoot, pLastNodeInList);
pLastNodeInList->right = pFirstNodeInList;
pFirstNodeInList->left = pLastNodeInList;
return pFirstNodeInList;
}
void convertTreeRecursively(Node* pRoot, Node* &pLastNodeInList){
if(pRoot != nullptr){
convertTreeRecursively(pRoot->left, pLastNodeInList);
pRoot->left = pLastNodeInList;
if(pLastNodeInList != nullptr){
pLastNodeInList->right = pRoot;
}
pLastNodeInList = pRoot;
convertTreeRecursively(pRoot->right, pLastNodeInList);
}
}
};
class Solution {
public:
Node* treeToDoublyList(Node* root) {
if(!root) return root;
stack<Node*> st;
Node* pre=nullptr, *head=root;
while(root || !st.empty()) {
if(root) {
st.push(root);
cout<<root->val<<endl;
root = root->left;
} else {
root = st.top();
st.pop();
if(pre == nullptr) {
pre = root;
head = root;
} else {
pre->right = root;
root->left = pre;
pre = root;
}
root = root->right;
}
}
pre->right = head;
head->left = pre;
return head;
}
};
面试题37. 序列化二叉树
class Codec {
public:
string serialize(TreeNode* root) {
ostringstream out;
serialize(root, out);
return out.str();
}
TreeNode* deserialize(string data) {
istringstream in(data);
return deserialize(in);
}
void serialize(TreeNode* root, ostringstream& out){
if(root){
out << root->val << ' ';
serialize(root->left, out);
serialize(root->right, out);
}else{
out << "# ";
}
}
TreeNode* deserialize(istringstream& in){
string val;
in >> val;
if(val == "#"){
return nullptr;
}
TreeNode* root = new TreeNode(stoi(val));
root->left = deserialize(in);
root->right = deserialize(in);
return root;
}
};
面试题38. 字符串的排列
class Solution {
public:
vector<string> permutation(string str) {
int length = str.length();
vector<string> res;
if(length == 0)
return res;
permutationRecursively(str, 0, length, res);
return res;
}
void permutationRecursively(string str, int mStart, int length, vector<string> &res){
if(mStart == length){
res.push_back(str);
return;
}
for(int i = mStart; i < length; i++){
bool duplication = false;
for(int j = mStart; j < i; j++){
if(str[j] == str[i]){
duplication = true;
break;
}
}
if(duplication) continue;
swap(str[mStart], str[i]);
permutationRecursively(str, mStart+1, length, res);
swap(str[mStart], str[i]);
}
}
};
面试题39. 数组中出现次数超过一半的数字
class Solution {
public:
int majorityElement(vector<int> &numbers) {
int length = numbers.size();
if(length == 0)
return 0;
int resNum = numbers[0];
int mCount = 1;
for(int i=1; i < length; i++){
if(numbers[i] == resNum)
mCount++;
else
mCount--;
if(mCount == 0){
resNum = numbers[i];
mCount = 1;
}
}
if(verifyNum(numbers, length, resNum))
return resNum;
return 0;
}
bool verifyNum(vector<int> numbers, int length, int resNum){
vector<int>::iterator iter;
int sum = 0;
for(iter = numbers.begin(); iter < numbers.end(); iter++){
if(*iter == resNum)
sum++;
}
if(sum > length/2)
return true;
else
return false;
}
};
面试题40. 最小的k个数
class Solution {
public:
vector<int> getLeastNumbers(vector<int> &input, int k) {
vector<int> res;
int length = input.size();
if(length == 0 || k <= 0 || k > length)
return res;
int low = 0;
int high = length - 1;
while(low <= high){
int indexOfk = mPartition(input, low, high);
if(indexOfk == k-1)
break;
if(indexOfk < k-1)
low = indexOfk + 1;
else
high = indexOfk - 1;
}
for(int i=0; i < k; i++)
res.push_back(input[i]);
return res;
}
int mPartition(vector<int> &data, int low, int high){
int temp = data[low];
while(low < high){
while(low < high && data[high] >= temp)
high--;
data[low] = data[high];
while(low < high && data[low] <= temp)
low++;
data[high] = data[low];
}
data[low] = temp;
return low;
}
};
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& nums, int k) {
vector<int> ans;
if(k == 0)
return ans;
priority_queue<int, vector<int>, less<int> > pq;
for(auto num: nums){
pq.push(num);
if(pq.size() > k)
pq.pop();
}
while(!pq.empty()){
ans.push_back(pq.top());
pq.pop();
}
return ans;
}
};
面试题41. 数据流中的中位数
class MedianFinder {
public:
MedianFinder() {
}
void addNum(int num){
int grossSum = mMax.size() + mMin.size();
if(grossSum & 1){
if(!mMin.empty() && num > mMin.top()){
int temp = mMin.top();
mMin.pop();
mMin.push(num);
num = temp;
}
mMax.push(num);
}else{
if(!mMax.empty() && num < mMax.top()){
int temp = mMax.top();
mMax.pop();
mMax.push(num);
num = temp;
}
mMin.push(num);
}
}
double findMedian(){
int grossSum = mMax.size() + mMin.size();
if(grossSum & 1)
return (double)(mMin.top());
else
return (double)(mMax.top() + mMin.top()) / 2;
}
private:
priority_queue<int, vector<int>, less<int> > mMax;
priority_queue<int, vector<int>, greater<int> > mMin;
};
面试题42. 连续子数组的最大和
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int length = nums.size();
if(length == 0)
return 0;
int res = nums[0];
int temp = nums[0];
for(int i = 1; i < length; i++){
temp = max(temp + nums[i], nums[i]);
res = max(res, temp);
}
return res;
}
};
面试题43. 1~n整数中1出现的次数
class Solution {
public:
int countDigitOne(int n){
if(n <= 0)
return 0;
string str = to_string(n);
return mySolutionRecursively(str);
}
int mySolutionRecursively(string str){
int length = str.size();
if(length == 1){
if(str[0] == '0')
return 0;
else
return 1;
}
int firstNum = str[0] - '0';
int amountOfFirstDigit = 0;
if(firstNum == 1)
amountOfFirstDigit = stoi(str.substr(1)) + 1;
else if(firstNum > 1)
amountOfFirstDigit = (int)pow(10, length-1);
int amountOfOtherDigit = 0;
amountOfOtherDigit = firstNum * (length-1) * (int)pow(10, length-2);
return amountOfFirstDigit + amountOfOtherDigit + mySolutionRecursively(str.substr(1));
}
};
面试题44. 数字序列中某一位的数字
class Solution {
public:
int findNthDigit(int index) {
int digits = 1;
while(true){
long long nums = cntOfNum(digits);
if(index < nums * digits)
return findNthDigit(index, digits);
index -= nums * digits;
digits++;
}
return -1;
}
int cntOfNum(int digits){
if(digits == 1)
return 10;
else
return 9 * (int)pow(10, digits-1);
}
int findNthDigit(int index, int digits){
int number = beginNumber(digits) + index / digits;
int indexFromRight = digits - index % digits;
while(--indexFromRight){
number /= 10;
}
return number % 10;
}
int beginNumber(int digits){
return digits == 1? 0: (int)pow(10, digits-1);
}
};
面试题45. 把数组排成最小的数
class Solution {
public:
string minNumber(vector<int>& nums) {
if(nums.size() == 0)
return "";
sort(nums.begin(), nums.end(), cmp);
string ret = "";
for(auto elem: nums)
ret += to_string(elem);
return ret;
}
static bool cmp(int a, int b){
string str_a = to_string(a) + to_string(b);
string str_b = to_string(b) + to_string(a);
return str_a < str_b;
}
};
面试题46. 把数字翻译成字符串
class Solution {
public:
int translateNum(int num) {
string str = to_string(num);
int length = str.size();
if(length == 0)
return 0;
int dp[length] = {0};
for(int i = length-1; i >= 0; i--){
int temp = 0;
if(i == length-1){
dp[i] = ++temp;
}
if(i <= length-2){
temp += dp[i+1];
int twoDigitsNum = 10 * (str[i] - '0') + (str[i+1] - '0');
if(twoDigitsNum >= 10 && twoDigitsNum <= 25){
if(i == length-2)
temp += 1;
else
temp += dp[i+2];
}
}
dp[i] = temp;
}
return dp[0];
}
};
面试题47. 礼物的最大价值
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size();
if(m == 0)
return 0;
int n = grid[0].size();
vector<vector<int> > dp(m + 1, vector<int>(n + 1, 0));
for(int i = 1; i <= m; i++){
for(int j = 1; j <= n; j++){
if(i == 1 && j == 1){
dp[i][j] = grid[0][0];
continue;
}
dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + grid[i-1][j-1];
}
}
return dp[m][n];
}
};
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size();
if(m == 0)
return 0;
int n = grid[0].size();
vector<int> dp(n, 0);
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
int left = 0;
int up = 0;
if(i > 0)
up = dp[j];
if(j > 0)
left = dp[j-1];
dp[j] = max(left, up) + grid[i][j];
}
}
return dp[n-1];
}
};
面试题48. 最长不含重复字符的子字符串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int length = s.length();
if(length <= 1)
return length;
unordered_map<char, int> uMap;
int curMax = 1;
uMap[s[0]] = 0;
int res = 0;
for(int i = 1; i < length; i++){
if(uMap.count(s[i]) == 0 || i - uMap[s[i]] > curMax){
curMax++;
}else{
curMax = i - uMap[s[i]];
}
res = max(res, curMax);
uMap[s[i]] = i;
}
return res;
}
};
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int left = 0, right = 0;
unordered_map<char, int> window;
int res = 0;
while (right < s.size()) {
char c1 = s[right];
window[c1]++;
while (window[c1] > 1) {
char c2 = s[left];
window[c2]--;
left++;
}
res = max(res, right - left + 1);
right++;
}
return res;
}
};
面试题49. 丑数
class Solution {
public:
int nthUglyNumber(int index) {
if(index <= 0)
return 0;
int res[index+1];
res[1] = 1;
int indexOf2 = 1;
int indexOf3 = 1;
int indexOf5 = 1;
for(int i = 2; i <= index; i++){
while(res[indexOf2]*2 <= res[i-1])
indexOf2++;
while(res[indexOf3]*3 <= res[i-1])
indexOf3++;
while(res[indexOf5]*5 <= res[i-1])
indexOf5++;
res[i] = mMin(res[indexOf2]*2, res[indexOf3]*3, res[indexOf5]*5);
}
return res[index];
}
int mMin(int a, int b, int c){
int temp = a < b? a: b;
return temp < c? temp: c;
}
};
面试题50. 第一个只出现一次的字符
class Solution {
public:
char firstUniqChar(string str) {
int length = str.length();
if(length <= 0)
return ' ';
int pos[256];
memset(pos, -1, sizeof(pos));
for(int i = 0; i < length; i++){
if(pos[str[i]] == -1)
pos[str[i]] = i;
else if(pos[str[i]] >= 0)
pos[str[i]] = -2;
}
for(int i=0; i < length; i++){
if(pos[str[i]] >= 0)
return str[i];
}
return ' ';
}
};
面试题51. 数组中的逆序对
typedef long long LL;
class Solution {
public:
int reversePairs(vector<int> mData) {
int length = mData.size();
if(length == 0)
return 0;
vector<int> mCopy(mData);
return amountOfInversePairs(mData, mCopy, 0, length-1);
}
LL amountOfInversePairs(vector<int> &mData, vector<int> &mCopy, int mStart, int mEnd){
if(mStart == mEnd){
mCopy[mStart] = mData[mStart];
return 0;
}
LL halfLength = (mEnd - mStart) / 2;
LL left = amountOfInversePairs(mCopy, mData, mStart, mStart + halfLength);
LL right = amountOfInversePairs(mCopy, mData, mStart + halfLength + 1, mEnd);
LL i = mStart + halfLength;
LL j = mEnd;
LL indexOfmCopy = mEnd;
LL mCount = 0;
while(i >= mStart && j >= mStart + halfLength + 1){
if(mData[i] > mData[j]){
mCount += j-mStart-halfLength;
mCopy[indexOfmCopy--] = mData[i--];
}else{
mCopy[indexOfmCopy--] = mData[j--];
}
}
while(i >= mStart)
mCopy[indexOfmCopy--] = mData[i--];
while(j >= mStart + halfLength + 1)
mCopy[indexOfmCopy--] = mData[j--];
return left + right + mCount;
}
};
面试题52. 两个链表的第一个公共节点
class Solution {
public:
ListNode* getIntersectionNode(ListNode* pHead1, ListNode* pHead2) {
if(pHead1 == nullptr || pHead2 == nullptr)
return nullptr;
ListNode* pFirstCommonNode = nullptr;
ListNode* pNodeInLongList = pHead1;
int lengthOfLongList = 0;
while(pNodeInLongList != nullptr){
lengthOfLongList++;
pNodeInLongList = pNodeInLongList->next;
}
ListNode* pNodeOfShortList = pHead2;
int lengthOfShortList = 0;
while(pNodeOfShortList != nullptr){
lengthOfShortList++;
pNodeOfShortList = pNodeOfShortList->next;
}
pNodeInLongList = pHead1;
pNodeOfShortList = pHead2;
if(lengthOfLongList < lengthOfShortList){
swap(lengthOfLongList, lengthOfShortList);
swap(pNodeInLongList, pNodeOfShortList);
}
int diff = lengthOfLongList - lengthOfShortList;
for(int i = 0; i < diff; i++)
pNodeInLongList = pNodeInLongList->next;
while(pNodeInLongList && pNodeOfShortList){
if(pNodeInLongList == pNodeOfShortList){
pFirstCommonNode = pNodeInLongList;
break;
}
pNodeInLongList = pNodeInLongList->next;
pNodeOfShortList = pNodeOfShortList->next;
}
return pFirstCommonNode;
}
};
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == nullptr || headB == nullptr)
return nullptr;
ListNode *pA = headA, *pB = headB;
while (pA != pB) {
pA = pA == nullptr ? headB : pA->next;
pB = pB == nullptr ? headA : pB->next;
}
return pA;
}
};
面试题53 - I. 在排序数组中查找数字 I
class Solution {
public:
int search(vector<int> data ,int k) {
int length = data.size();
if(length == 0)
return 0;
int indexOfFirstK = getIndexOfFirstK(data, k);
int indexOfLastK = getIndexOfLastK(data, k);
if(indexOfFirstK >= 0 && indexOfLastK >= 0){
return indexOfLastK - indexOfFirstK + 1;
}
return 0;
}
int getIndexOfFirstK(vector<int> data ,int k){
int low = 0;
int high = data.size() - 1;
while(low <= high){
int mid = (low + high) >> 1;
if(data[mid] == k){
if(mid == 0 || data[mid-1] != k)
return mid;
high = mid - 1;
}else if(data[mid] < k){
low = mid + 1;
}else{
high = mid - 1;
}
}
return -1;
}
int getIndexOfLastK(vector<int> data ,int k){
int low = 0;
int high = data.size() - 1;
while(low <= high){
int mid = (low + high) >> 1;
if(data[mid] == k){
if(mid == data.size()-1 || data[mid+1] != k)
return mid;
low = mid + 1;
}else if(data[mid] < k){
low = mid + 1;
}else{
high = mid - 1;
}
}
return -1;
}
};
面试题53 - II. 0~n-1中缺失的数字
class Solution {
public:
int missingNumber(vector<int>& nums) {
int length = nums.size();
int left = 0, right = length - 1;
while(left < right){
int mid = left + ((right - left) >> 1);
if(nums[mid] == mid)
left = mid + 1;
else
right = mid;
}
if(left != nums[left])
return left;
else
return length;
}
};
面试题54. 二叉搜索树的第k大节点
class Solution {
public:
int kthLargest(TreeNode* root, int k) {
if(root == nullptr || k <= 0)
return 0;
return KthNode(root, k)->val;
}
TreeNode* KthNode(TreeNode* pRoot, int &k)
{
if(pRoot == nullptr || k <= 0)
return nullptr;
TreeNode* pAns = nullptr;
pAns = KthNode(pRoot->right, k);
if(pAns == nullptr){
k--;
if(k == 0)
pAns = pRoot;
}
if(pAns == nullptr)
pAns = KthNode(pRoot->left, k);
return pAns;
}
};
class Solution {
public:
int n=0;
int res;
int kthLargest(TreeNode* root, int k) {
dfs(root, k);
return res;
}
void dfs(TreeNode* root, int k){
if(!root)
return ;
dfs(root->right, k);
n++;
if(n == k)
res = root->val;
dfs(root->left, k);
}
};
面试题55 - I. 二叉树的深度
class Solution {
public:
int maxDepth(TreeNode* pRoot)
{
if(pRoot == nullptr)
return 0;
int left = maxDepth(pRoot->left);
int right = maxDepth(pRoot->right);
return max(left, right) + 1;
}
};
面试题55 - II. 平衡二叉树
class Solution {
public:
bool isBalanced(TreeNode* pRoot) {
if(pRoot == nullptr)
return true;
int left = TreeDepth(pRoot->left);
int right = TreeDepth(pRoot->right);
int diff = left - right;
if(diff > 1 || diff < -1)
return false;
return isBalanced(pRoot->left) && isBalanced(pRoot->right);
}
int TreeDepth(TreeNode* pRoot){
if(pRoot == nullptr)
return 0;
int left = TreeDepth(pRoot->left);
int right = TreeDepth(pRoot->right);
return max(left, right) + 1;
}
};
class Solution {
public:
bool isBalanced(TreeNode* root) {
res = true;
getDepth(root);
return res;
}
int getDepth(TreeNode* root){
if(root == nullptr)
return 0;
int left = getDepth(root->left);
int right = getDepth(root->right);
if(abs(left - right) > 1)
res = false;
return max(left, right) + 1;
}
private:
bool res;
};
面试题56 - I. 数组中数字出现的次数
class Solution {
public:
vector<int> singleNumbers(vector<int> &nums) {
int length = nums.size();
vector<int> res;
if(length == 0)
return res;
int temp = 0;
for(int i = 0; i < length; i++)
temp ^= nums[i];
if(temp == 0)
return res;
int posOfLast1 = getPosOfLast1(temp);
int num1 = 0, num2 = 0;
for(int i = 0; i < length; i++){
if(nums[i] & (1<<posOfLast1))
num1 ^= nums[i];
else
num2 ^= nums[i];
}
res.push_back(num1), res.push_back(num2);
return res;
}
int getPosOfLast1(int a){
int posOfLast1 = 0;
int bitMask = 1;
while((a&bitMask) == 0){
bitMask = bitMask << 1;
posOfLast1++;
}
return posOfLast1;
}
};
面试题56 - II. 数组中数字出现的次数 II
class Solution {
public:
int singleNumber(vector<int>& nums) {
int length = nums.size();
int bitSum[32] = {0};
for(int i = 0; i < length; i++){
unsigned int bitMask = 1;
for(int j = 31; j >= 0; j--){
if((nums[i] & bitMask) != 0)
bitSum[j]++;
bitMask <<= 1;
}
}
int res = 0;
for(int i = 0; i < 32; i++){
res <<= 1;
res += bitSum[i] % 3;
}
return res;
}
};
面试题57 - I. 和为s的两个数字
class Solution {
public:
vector<int> twoSum(vector<int> data, int sum) {
int length = data.size();
vector<int> res;
if(length == 0)
return res;
int low = 0;
int high = length - 1;
while(low < high){
if(data[low] + data[high] == sum){
res.push_back(data[low]);
res.push_back(data[high]);
return res;
}
if(data[low] + data[high] > sum)
high--;
else
low++;
}
return res;
}
};
面试题57 - II. 和为s的连续正数序列
class Solution {
public:
vector<vector<int> > findContinuousSequence(int k) {
vector<vector<int> > res;
if(k <= 2)
return res;
int low = 1;
int high = 2;
int midVal = (k + 1) / 2;
int sum = low + high;
while(low <= midVal){
if(sum == k){
vector<int> temp;
for(int i = low; i <= high; i++)
temp.push_back(i);
res.push_back(temp);
sum -= low;
low++;
continue;
}
if(sum > k){
sum -= low;
low++;
}else{
high++;
sum += high;
}
}
return res;
}
};
面试题58 - I. 翻转单词顺序
class Solution {
public:
string reverseWords(string str) {
string res = str;
int length = str.length();
if(length == 0)
return res;
mReverse(res, 0, length-1);
int start = 0;
for (int i = 0; i < res.length(); i++) {
if (res[i] == ' ') {
mReverse(res, start, i - 1);
start = i + 1;
}
}
mReverse(res, start, res.length()-1);
int left = 0;
while(left < res.size() && res[left] == ' ') left++;
int right = res.size() - 1;
while(right >= 0 && res[right] == ' ') right--;
res = res.substr(left, right-left+1);
int tail = 0;
for(int i = 0; i < res.size(); i++){
if(i < res.size()-1 && res[i] == ' ' && res[i+1] == ' ')
continue;
res[tail++] = res[i];
}
return res.substr(0, tail);
}
void mReverse(string &str, int low, int high){
while(low < high){
swap(str[low], str[high]);
low++;
high--;
}
}
};
面试题58 - II. 左旋转字符串
class Solution {
public:
string reverseLeftWords(string str, int n) {
int length = str.size();
n = n % length;
mReverse(str, 0, length - 1);
mReverse(str, 0, length - 1 - n);
mReverse(str, length - n, length - 1);
return str;
}
void mReverse(string &str, int low, int high){
while(low < high){
swap(str[low], str[high]);
low++;
high--;
}
}
};
面试题59 - I. 滑动窗口的最大值
class Solution {
public:
vector<int> maxSlidingWindow(const vector<int>& data, unsigned int sizeOfWindows){
vector<int> res;
int length = data.size();
if(length == 0 || sizeOfWindows <= 0 || sizeOfWindows > length)
return res;
deque<int> maxQue;
for(int i = 0; i < sizeOfWindows; i++){
while(!maxQue.empty() && data[i] >= data[maxQue.back()])
maxQue.pop_back();
maxQue.push_back(i);
}
res.push_back(data[maxQue.front()]);
for(int i = sizeOfWindows; i < length; i++){
while(!maxQue.empty() && i-maxQue.front() >= sizeOfWindows)
maxQue.pop_front();
while(!maxQue.empty() && data[i] >= data[maxQue.back()])
maxQue.pop_back();
maxQue.push_back(i);
res.push_back(data[maxQue.front()]);
}
return res;
}
};
面试题59 - II. 队列的最大值
class MaxQueue {
public:
MaxQueue() {
}
int max_value() {
if(dq.empty())
return -1;
return dq.front();
}
void push_back(int value) {
q.push(value);
while(!dq.empty() && value > dq.back())
dq.pop_back();
dq.push_back(value);
}
int pop_front() {
if(q.empty())
return -1;
int res = q.front();
q.pop();
if(!dq.empty() && res == dq.front())
dq.pop_front();
return res;
}
private:
queue<int> q;
deque<int> dq;
};
面试题60. n个骰子的点数
int g_maxValue = 6;
class Solution {
public:
vector<double> twoSum(int n) {
int maxSum = g_maxValue * n;
vector<int> cnts(maxSum - n + 1, 0);
cntOfDifferentSum(n, 0, 0, cnts);
vector<double> res(maxSum - n + 1);
int total = (int)pow(g_maxValue, n);
for(int i = 0; i < cnts.size(); i++){
res[i] = (double)cnts[i] / total;
}
return res;
}
void cntOfDifferentSum(int n, int curSum, int index, vector<int> &cnts){
if(index == n){
cnts[curSum-n]++;
return;
}
for(int i = 1; i <= g_maxValue; i++){
cntOfDifferentSum(n, curSum + i, index + 1, cnts);
}
}
};
int g_maxValue = 6;
class Solution {
public:
vector<double> twoSum(int n) {
int maxSum = g_maxValue * n;
vector<int> cnts(maxSum - n + 1, 0);
vector<vector<int> > dp(2, vector<int>(n * g_maxValue + 1, 0));
int flag = 0;
for(int i = 1; i <= g_maxValue; i++){
dp[flag][i] = 1;
}
for(int k = 2; k <= n; k++){
for(int i = 0; i < k; i++)
dp[1-flag][i] = 0;
for(int i = k; i <= g_maxValue * k; i++){
dp[1-flag][i] = 0;
for(int j = 1; j <= g_maxValue && j <= i; j++)
dp[1-flag][i] += dp[flag][i-j];
}
flag = 1 - flag;
}
vector<double> res(maxSum - n + 1);
int total = (int)pow(g_maxValue, n);
for(int i = n; i <= g_maxValue * n; i++){
res[i-n] = (double)dp[flag][i] / total;
}
return res;
}
};
面试题61. 扑克牌中的顺子
class Solution {
public:
bool isStraight(vector<int> data) {
int length = data.size();
if(length == 0)
return false;
int numOfKing = 0;
for(int i = 0; i < length; i++){
if(data[i] == 0)
numOfKing++;
}
sort(data.begin(), data.end());
int mBegin = 0;
for(; mBegin < length; mBegin++){
if(data[mBegin] != 0)
break;
}
if(mBegin == length)
return true;
int numOfGap = 0;
int mEnd = mBegin + 1;
while(mEnd <= length-1){
if(data[mBegin] == data[mEnd])
return false;
numOfGap += (data[mEnd] - data[mBegin] - 1);
mBegin++;
mEnd++;
}
if(numOfGap <= numOfKing)
return true;
else
return false;
}
};
面试题62. 圆圈中最后剩下的数字
class Solution {
public:
int lastRemaining(int n, int m){
if(n <= 0 || m <= 0)
return -1;
list<int> mList;
for(int i = 0; i < n; i++)
mList.push_back(i);
list<int>::iterator current = mList.begin();
while(mList.size() != 1){
for(int i = 0; i < m-1; i++){
current++;
if(current == mList.end()){
current = mList.begin();
}
}
list<int>::iterator next = ++current;
if(next == mList.end())
next = mList.begin();
current--;
mList.erase(current);
current = next;
}
return *mList.begin();
}
};
class Solution {
public:
int lastRemaining(int n, int m){
if(n <= 0 || m <= 0)
return -1;
int last = 0;
for(int i = 2; i <= n; i++)
last = (last+m) % i;
return last;
}
};
面试题63. 股票的最大利润
class Solution {
public:
int maxProfit(vector<int>& prices) {
int maxDiff = 0;
int length = prices.size();
if(length < 2)
return maxDiff;
if(prices[1] >= prices[0])
maxDiff = prices[1] - prices[0];
int preMin = prices[0];
for(int i = 2; i < length; i++){
preMin = min(preMin, prices[i-1]);
maxDiff = max(maxDiff, prices[i] - preMin);
}
return maxDiff;
}
};
class Solution {
public:
int maxProfit(vector<int>& prices) {
int length = prices.size();
if(length <= 1)
return 0;
int dp_i_0 = 0, dp_i_1 = -prices[0];
for (int i = 1; i < length; i++) {
dp_i_0 = max(dp_i_0, dp_i_1 + prices[i]);
dp_i_1 = max(dp_i_1, -prices[i]);
}
return dp_i_0;
}
};
面试题64. 求1+2+…+n
class mAdd{
public:
mAdd(){
i++;
sum += i;
}
static void mReset(){
i = 0;
sum = 0;
}
static int getSum(){
return sum;
}
private:
static int i;
static int sum;
};
int mAdd::i = 0;
int mAdd::sum = 0;
class Solution {
public:
int sumNums(int n) {
mAdd::mReset();
mAdd a[n];
return mAdd::getSum();
}
};
class Solution {
public:
int sumNums(int n) {
n && (n += sumNums(n-1));
return n;
}
};
面试题65. 不用加减乘除做加法
class Solution {
public:
int add(int num1, int num2){
do{
int temp = num1 ^ num2;
int carry = (unsigned int)(num1 & num2) << 1;
num1 = temp;
num2 = carry;
}while(num2);
return num1;
}
};
面试题66. 构建乘积数组
class Solution {
public:
vector<int> constructArr(const vector<int>& A) {
vector<int> B;
int length = A.size();
if(length == 0)
return B;
int curProduct = 1;
for(int i = 0; i < length; i++){
if(i == 0){
B.push_back(curProduct);
curProduct *= A[i];
continue;
}
B.push_back(curProduct);
curProduct *= A[i];
}
curProduct = 1;
for(int i = length-1; i >= 0; i--){
if(i == length-1){
curProduct *= A[i];
continue;
}
B[i] *= curProduct;
curProduct *= A[i];
}
return B;
}
};
面试题67. 把字符串转换成整数
class Solution {
public:
int strToInt(string str) {
int res = 0;
int i = 0;
int flag = 1;
while (str[i] == ' ') { i++; }
if (str[i] == '-') { flag = -1; }
if (str[i] == '+' || str[i] == '-') { i++; }
while (i < str.size() && isdigit(str[i])) {
int r = str[i] - '0';
if (res > INT_MAX / 10 || (res == INT_MAX / 10 && r > 7)) {
return flag > 0 ? INT_MAX : INT_MIN;
}
res = res * 10 + r;
i++;
}
return flag > 0 ? res : -res;
}
};
class Solution {
public:
int strToInt(string str) {
int res = 0;
int i = 0;
int flag = 1;
while (str[i] == ' ') { i++; }
if (str[i] == '-') { flag = -1; }
if (str[i] == '+' || str[i] == '-') { i++; }
while (i < str.size() && isdigit(str[i])) {
int r = str[i] - '0';
if (flag == 1 && (res > INT_MAX / 10 || (res == INT_MAX / 10 && r >= 7))) {
return INT_MAX;
}
if (flag == -1 && (res > INT_MAX / 10 || (res == INT_MAX / 10 && r >= 8))) {
return INT_MIN;
}
res = res * 10 + r;
i++;
}
return flag > 0 ? res : -res;
}
};
面试题68 - I. 二叉搜索树的最近公共祖先
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == nullptr || p == nullptr || q == nullptr)
return nullptr;
if((root->val >= p->val && root->val <= q->val) || (root->val >= q->val && root->val <= p->val))
return root;
else if(root->val > p->val && root->val > q->val)
return lowestCommonAncestor(root->left, p, q);
else
return lowestCommonAncestor(root->right, p, q);
}
};
面试题68 - II. 二叉树的最近公共祖先
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == nullptr || root == p || root == q)
return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left != nullptr && right != nullptr)
return root;
return left == nullptr? right: left;
}
};