剑指 Offer 05. 替换空格
class Solution {
public:
string replaceSpace(string s) {
int len = s.size();
string g;
for(int i = 0; i < len; i++)
{
if(s[i] == ' ')
{
g += "%20";
continue;
}
g += s[i];
}
return g;
}
};
剑指 Offer 58 - II. 左旋转字符串
class Solution {
public:
void Reverse(string &a,int left,int right)
{
while(left < right)
{
char temp = a[left];
a[left] = a[right];
a[right] = temp;
left++;
right--;
}
}
string reverseLeftWords(string s, int n) {
int len = s.size();
if(n >= len)
{
n %= len;
}
Reverse(s,0,n-1);
Reverse(s,n,len-1);
Reverse(s,0,len-1);
return s;
}
};
剑指 Offer 67. 把字符串转换成整数❤️
class Solution {
public:
int strToInt(string str)
{
int len = str.size();
int i = 0;
int flag = 1;
long long num = 0;
while(str[i] == ' ')
{
i++;
}
if(str[i] == '+'||str[i] == '-')
{
if(str[i] =='-')
flag = -flag;
i++;
}
while(i < len && str[i] >= '0' && str[i] <= '9')
{
num = num*10+(str[i]-'0')*flag;
i++;
if(flag == -1 && num < INT_MIN )
{
return INT_MIN;
}
if(flag == 1 && num > INT_MAX )
{
return INT_MAX;
}
}
if(i != len)
{
return num;
}
return num;
}
};
剑指 Offer 06. 从尾到头打印链表
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int>ret;
while(head!=NULL)
{
ret.insert(ret.begin(),head->val);
head = head->next;
}
return ret;
}
};
剑指 Offer 24. 反转链表
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == nullptr)
{
return nullptr;
}
ListNode * n1 = nullptr;
ListNode * n2 = head;
ListNode * n3 = head->next;
while(n2 != nullptr)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if(n3 != nullptr)
{
n3 = n3->next;
}
}
return n1;
}
};
剑指 Offer 35. 复杂链表的复制
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
Node * cur = head;
while(cur)
{
Node * ne = cur->next;
Node * newNode = (Node*)malloc(sizeof(Node));
newNode->val = cur->val;
newNode->next = ne;
cur->next = newNode;
cur = ne;
}
cur = head;
while(cur)
{
Node * ne = cur->next;
Node * nene = cur->next->next;
if(cur->random == nullptr)
{
cur->next->random = nullptr;
}
else
{
cur->next->random = cur->random->next;
}
cur = nene;
}
Node * newNode1 =nullptr;
Node * tail = nullptr;
cur = head;
while(cur)
{
Node * ne = cur->next;
Node * nene = cur->next->next;
if(newNode1 == nullptr)
{
newNode1 = tail = ne;
}
else
{
tail->next = ne;
tail = tail->next;
}
cur->next = nene;
cur = nene;
}
return newNode1;
}
};
剑指 Offer 18. 删除链表的节点
class Solution {
public:
ListNode* deleteNode(ListNode* head, int val) {
ListNode * cur = head;
ListNode * prev = nullptr;
while(cur)
{
ListNode * ne = cur->next;
if(cur->val == val)
{
if(head == cur)
{
head = ne;
cur = head;
}
else
{
prev->next = ne;
cur = prev->next;
}
}
else
{
prev = cur;
cur = ne;
}
}
return head;
}
};
剑指 Offer 22. 链表中倒数第k个节点
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode * slow = head;
ListNode * fast = head;
while(k--)
{
fast = fast->next;
}
while(fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
};
剑指 Offer 25. 合并两个排序的链表
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
{
ListNode * newHead = (ListNode*)malloc(sizeof(ListNode));
newHead->next = nullptr;
ListNode * tail = newHead;
while(l1 != nullptr && l2 != nullptr)
{
if(l1->val <= l2->val)
{
tail->next = l1;
tail = tail->next;
l1 = l1->next;
}
else
{
tail->next = l2;
tail = tail->next;
l2 = l2->next;
}
}
if(l1 != nullptr)
{
tail->next = l1;
}
if(l2 != nullptr)
{
tail->next = l2;
}
return newHead->next;
}
};
剑指 Offer 52. 两个链表的第一个公共节点
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode * curA = headA;
ListNode * curB = headB;
int countA = 0;
int countB = 0;
while(curA)
{
curA = curA->next;
countA++;
}
while(curB)
{
curB = curB->next;
countB++;
}
if(countA > countB)
{
countA -= countB;
while(countA--)
{
headA = headA->next;
}
}
else
{
countB -= countA;
while(countB--)
{
headB = headB->next;
}
}
while(headA != nullptr && headB != nullptr)
{
if(headA == headB)
{
return headA;
}
headA = headA->next;
headB = headB->next;
}
return nullptr;
}
};
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
class Solution {
public:
void exchange(vector<int>&nums,int len)
{
int * ret = (int*)malloc(sizeof(int) * (len + 1));
int j = 0;
for(int i = 0; i < len; i++)
{
if((nums[i] & 1) == 1)
{
ret[j++] = nums[i];
}
}
for(int i = 0; i < len; i++)
{
if((nums[i] & 1 )== 0)
{
ret[j++] = nums[i];
}
}
for(int i = 0; i < len; i++)
{
nums[i] = ret[i];
}
}
vector<int> exchange(vector<int>& nums) {
int len = nums.size();
exchange(nums,len);
return nums;
}
};
剑指 Offer 57. 和为s的两个数字
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int len = nums.size();
unordered_map<int,int>hash;
vector<int>ret;
for(int i = 0; i < len; i++)
{
int num = target - nums[i];
if(hash.count(num))
{
ret.push_back(num);
ret.push_back(nums[i]);
break;
}
hash.insert({nums[i],i});
}
return ret;
}
};
剑指 Offer 59 - I. 滑动窗口的最大值
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
int len = nums.size();
deque<int>q;
vector<int>ret;
for(int i = 0; i < nums.size(); i++)
{
if(!q.empty() && i - k + 1 > q[0]) q.pop_front();
while(!q.empty() && nums[q[q.size()-1]] <= nums[i]) q.pop_back();
q.push_back(i);
if(i >= k - 1)
{
ret.push_back(nums[q[0]]);
}
}
return ret;
}
};
剑指 Offer 58 - I. 翻转单词顺序
class Solution {
public:
string reverseWords(string s) {
string ret;
int i = 0;
int num = s.size();
while(i < num)
{
if(s[i] != ' ')
{
break;
}
i++;
}
while(s.size() > 0)
{
int num = s.size();
if(s[num-1] != ' ')
{
break;
}
s.pop_back();
}
int len = s.size();
if(len == 0) return s;
while(i < len)
{
int cnt = 0;
int begin = ret.size();
while(i < len && s[i] != ' ')
{
ret += s[i];
i++;
}
int end = ret.size();
reverse(ret.begin()+begin,ret.begin()+end);
while(i < len && s[i] == ' ')
{
cnt++;
if(cnt == 1)
{
ret += s[i];
}
i++;
}
}
int num1 = ret.size();
reverse(ret.begin(),ret.end());
return ret;
}
};
剑指 Offer 09. 用两个栈实现队列
class CQueue {
public:
CQueue() {
}
void appendTail(int value) {
p_push.push(value);
}
int deleteHead() {
if(p_push.empty() && p_pop.empty())
{
return -1;
}
if(!p_pop.empty())
{
int top = p_pop.top();
p_pop.pop();
return top;
}
else
{
while(!p_push.empty())
{
p_pop.push(p_push.top());
p_push.pop();
}
}
int top = p_pop.top();
p_pop.pop();
return top;
}
private:
stack<int>p_push;
stack<int>p_pop;
};
剑指 Offer 30. 包含min函数的栈❤️
class MinStack {
stack<int>x_push;
stack<int>min_push;
public:
MinStack() {
min_push.push(INT_MAX);
}
void push(int x)
{
x_push.push(x);
min_push.push(std::min(min_push.top(),x));
}
void pop() {
x_push.pop();
min_push.pop();
}
int top() {
return x_push.top();
}
int min() {
return min_push.top();
}
};
剑指 Offer 59 - II. 队列的最大值❤️
class MaxQueue {
public:
deque<int>val;
deque<int>vmax;
MaxQueue() {
}
int max_value() {
if(vmax.empty())
{
return -1;
}
return vmax.front();
}
void push_back(int value) {
while((!vmax.empty()) && (vmax.back() < value))
{
vmax.pop_back();
}
val.push_back(value);
vmax.push_back(value);
}
int pop_front() {
if(val.empty())
{
return -1;
}
int ans = vmax.front();
if(ans == val.front())
{
vmax.pop_front();
}
int front = val.front();
val.pop_front();
return front;
}
};
剑指 Offer 29. 顺时针打印矩阵❤️
class Solution {
private:
bool flag[110][110]= {false};
int d[4][2]= {{0,1},{1,0},{0,-1},{-1,0}};
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int>ret;
if (matrix.size() == 0 || matrix[0].size() == 0) return ret;
int rows = matrix.size(),cols = matrix[0].size();
int sum = rows * cols;
int tal = 0;
int row = 0,col = 0;
int dir = 0;
for(int i = 0; i < sum; i++)
{
ret.push_back( matrix[row][col]);
flag[row][col] = true;
int a = row + d[dir][0],b = col + d[dir][1];
if(a < 0 || a >= rows || b < 0 || b >= cols || flag[a][b])
{
dir = (dir + 1) % 4;
}
row += d[dir][0];
col += d[dir][1];
}
return ret;
}
};
剑指 Offer 31. 栈的压入、弹出序列
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int>st;
int n = pushed.size();
int j = 0;
for(int i = 0; i < n; i++)
{
st.push(pushed[i]);
while(!st.empty() && st.top() == popped[j])
{
j++;
st.pop();
}
}
return st.empty();
}
};
剑指 Offer 03. 数组中重复的数字
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
unordered_map<int,int>hash;
int k = 0;
for(int i = 0; i < nums.size(); i++)
{
if(hash.count(nums[i]))
{
k = i;
return nums[k];
}
hash.insert({nums[i],i});
}
return nums[k];
}
};
剑指 Offer 53 - I. 在排序数组中查找数字 I
class Solution {
public:
int search(vector<int>& nums, int target) {
int count = 0;
for(int i = 0; i < nums.size(); i++)
{
if(nums[i] > target)
{
break;
}
if(nums[i] == target)
{
count++;
}
}
return count;
}
};
剑指 Offer 53 - II. 0~n-1中缺失的数字
class Solution {
public:
int missingNumber(vector<int>& nums) {
int n = nums.size();
int sum = 0;
for(int i = 1; i <= n; i++)
{
sum += i;
}
for(int i = 0 ; i < n; i++)
{
sum -= nums[i];
}
return sum;
}
};
剑指 Offer 04. 二维数组中的查找
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
if(matrix.size() == 0 || matrix[0].size() == 0) return false;
int n = 0,m = matrix[0].size() - 1;
while(n < matrix.size() && m >=0)
{
if(matrix[n][m] > target) m--;
else if(matrix[n][m] < target) n++;
else return true;
}
return false;
}
};
剑指 Offer 11. 旋转数组的最小数字❤️
class Solution {
public:
int minArray(vector<int>& numbers) {
int n = numbers.size();
int left = 0,right = n - 1;
while(left < right)
{
int mid = left + right >> 1;
if(numbers[mid] > numbers[right]) left = mid + 1;
else if(numbers[mid] < numbers[right]) right = mid;
else right--;
}
return numbers[left];
}
};
剑指 Offer 50. 第一个只出现一次的字符
class Solution {
public:
char firstUniqChar(string s) {
if(s.size() == 0) return ' ';
vector<int>h;
int arr[26] = {0};
for(int i = 0; i < s.size(); i++)
{
arr[s[i] - 'a']++;
}
for(int i = 0; i < s.size(); i++)
{
if(arr[s[i] - 'a'] == 1)
{
return s[i];
}
}
return ' ';
}
};
class Solution {
public:
char firstUniqChar(string s) {
unordered_map<int, int> frequency;
for (char ch: s) {
++frequency[ch];
}
for (int i = 0; i < s.size(); ++i) {
if (frequency[s[i]] == 1) {
return s[i];
}
}
return ' ';
}
};
剑指 Offer 32 - I. 从上到下打印二叉树
class Solution {
public:
vector<int> levelOrder(TreeNode* root) {
if(root == nullptr)
{
return {};
}
queue<TreeNode*>q;
vector<int>ret;
q.push(root);
while(q.size())
{
TreeNode * front = q.front();
ret.push_back(front->val);
q.pop();
if(front->left != nullptr)
{
q.push(front->left);
}
if(front->right != nullptr)
{
q.push(front->right);
}
}
return ret;
}
};
剑指 Offer 32 - II. 从上到下打印二叉树 II
class Solution {
public:
int RootSize(TreeNode * root)
{
if(root == nullptr)
{
return 0;
}
int leftmax = RootSize(root->left);
int rightmax = RootSize(root->right);
return leftmax > rightmax ? leftmax + 1 : rightmax + 1;
}
vector<vector<int>> levelOrder(TreeNode* root) {
if(root == nullptr)
{
return {};
}
int num = RootSize(root);
typedef pair<TreeNode*,int>PII;
const int N = 1010;
PII q[N];
int hh = 0, tt = 0;
int i = 0;
vector<vector<int>>ret(num);
q[tt] = {root,i};
while(hh <= tt)
{
PII t = q[hh++];
TreeNode * front = t.first;
int k = t.second;
ret[k].push_back(front->val);
if(front->left != nullptr)
{
q[++tt] = {front->left,k + 1};
}
if(front->right != nullptr)
{
q[++tt] = {front->right,k + 1};
}
}
return ret;
}
};
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector <vector <int>> ret;
if (!root) {
return ret;
}
queue <TreeNode*> q;
q.push(root);
while (!q.empty()) {
int currentLevelSize = q.size();
ret.push_back(vector <int> ());
for (int i = 1; i <= currentLevelSize; ++i) {
auto node = q.front(); q.pop();
ret.back().push_back(node->val);
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
}
return ret;
}
};
剑指 Offer 32 - III. 从上到下打印二叉树 III
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
if(root == nullptr) return {};
queue<TreeNode*>q;
vector<vector<int>>ret;
q.push(root);
while(!q.empty())
{
int num = q.size();
ret.push_back(vector<int>());
for(int i = 0; i < num; i++)
{
auto node = q.front();
q.pop();
ret.back().push_back(node->val);
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
}
int k = ret.size();
for(int i = 0; i < k; i++)
{
if(i % 2 != 0)
{
reverse(ret[i].begin(),ret[i].end());
}
}
return ret;
}
};
剑指 Offer 26. 树的子结构❤️
class Solution {
public:
bool IsSame(TreeNode * A,TreeNode * B)
{
if(B == nullptr) return true;
if(A == nullptr) return false;
if(A->val == B->val)
{
return IsSame(A->left, B->left) && IsSame(A->right, B->right);
}
return false;
}
void TraverseTree(TreeNode * A,TreeNode * B,bool &flag)
{
if(A == nullptr) return;
TraverseTree(A->left,B,flag);
if(flag) return;
TraverseTree(A->right,B,flag);
if(A->val == B->val)
{
flag = IsSame(A,B);
}
}
bool isSubStructure(TreeNode* A, TreeNode* B) {
if(A == nullptr || B == nullptr) return false;
bool flag = false;
TraverseTree(A,B,flag);
return flag;
}
};
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if (A == NULL || B == NULL) return false;
if (A->val == B->val) {
if (dfs_isEqual(A, B)) {
return true;
}
}
return isSubStructure(A->left, B) || isSubStructure(A->right, B);
}
bool dfs_isEqual(TreeNode* A, TreeNode* B) {
if (B == NULL) return true;
if (A == NULL) return false;
if (A->val == B->val) {
return dfs_isEqual(A->left, B->left) && dfs_isEqual(A->right, B->right);
} else {
return false;
}
}
};
剑指 Offer 27. 二叉树的镜像
class Solution {
public:
TreeNode* mirrorTree(TreeNode* root) {
if(root == nullptr)
{
return root;
}
mirrorTree(root->left);
mirrorTree(root->right);
if(root->left != nullptr || root->right != nullptr)
{
TreeNode * tmp = root->left;
root->left = root->right;
root->right = tmp;
}
return root;
}
};
剑指 Offer 28. 对称的二叉树
class Solution {
public:
void mirrorTree(TreeNode * root)
{
if(root == nullptr) return;
mirrorTree(root->left);
mirrorTree(root->right);
if(root->left != nullptr || root->right != nullptr)
{
TreeNode * tmp = root->left;
root->left = root->right;
root->right = tmp;
}
return;
}
bool IsEmpty(TreeNode * A,TreeNode * B)
{
if(A == nullptr && B == nullptr) return true;
if(A == nullptr || B == nullptr) return false;
if(A->val == B->val)
{
return IsEmpty(A->left,B->left) && IsEmpty(A->right,B->right);
}
return false;
}
bool isSymmetric(TreeNode* root) {
if(root == nullptr) return true;
mirrorTree(root->right);
bool flag = IsEmpty(root->left,root->right);
return flag;
}
};
class Solution {
public:
bool check(TreeNode *p, TreeNode *q) {
if (!p && !q) return true;
if (!p || !q) return false;
return p->val == q->val && check(p->left, q->right) && check(p->right, q->left);
}
bool isSymmetric(TreeNode* root) {
return check(root, root);
}
};
剑指 Offer 12. 矩阵中的路径❤️
class Solution {
public:
bool IsEmpty(vector<vector<char>>& board, vector<vector<int>>&visited,
int rows,int cols,string word,int k)
{
int a = board.size(),b = board[0].size();
if(board[rows][cols] != word[k]) return false;
else if(k == word.size()-1) return true;
visited[rows][cols] = true;
bool result = false;
for(int i = 0; i < 4; i++)
{
int x = rows + dx[i],y = cols + dy[i];
if(x >= 0 && x < a && y >= 0 && y < b)
{
if(!visited[x][y])
{
bool flag = IsEmpty(board, visited, x, y, word, k + 1);
if(flag) return true;
}
}
}
visited[rows][cols] = false;
return result;
}
bool exist(vector<vector<char>>& board, string word) {
int row = board.size(),col = board[0].size();
vector<vector<int>>visited(row,vector<int>(col));
bool flag = false;
for(int i = 0; i < row; i++)
for(int j = 0; j < col; j++)
{
flag = IsEmpty(board,visited,i,j,word,0);
if(flag) return true;
}
return false;
}
private:
int dx[4] = {0,0,-1,1};
int dy[4] = {1,-1,0,0};
};
剑指 Offer 13. 机器人的运动范围❤️
class Solution {
public:
int get(int x)
{
int sum = 0;
while(x > 0)
{
sum += x % 10;
x /= 10;
}
return sum;
}
void check(vector<vector<int>>&ans, int row, int col, int k, int &res, int sum, int o)
{
if(sum > k) return;
res++;
int a = ans.size(),b = ans[0].size();
ans[row][col] = true;
for(int i = 0; i < 2; i++)
{
int x = row + dx[i], y = col + dy[i];
if(x >= 0 && x < a && y >= 0 && y < b && !ans[x][y])
{
int q = get(x), p = get(y);
int sum1 = p + q;
check(ans,x,y,k,res,sum1,o+1);
}
}
}
int movingCount(int m, int n, int k)
{
if(k == 0) return 1;
vector<vector<int>>ans(m,vector<int>(n));
int res = 0;
int o = 1;
int sum = 0;
check(ans,0,0,k,res,sum,o);
return res;
}
private:
int dx[4] = {1,0};
int dy[4] = {0,1};
};
class Solution {
int get(int x) {
int res=0;
for (; x; x /= 10) {
res += x % 10;
}
return res;
}
public:
int movingCount(int m, int n, int k) {
if (!k) return 1;
queue<pair<int,int> > Q;
int dx[2] = {0, 1};
int dy[2] = {1, 0};
vector<vector<int> > vis(m, vector<int>(n, 0));
Q.push(make_pair(0, 0));
vis[0][0] = 1;
int ans = 1;
while (!Q.empty()) {
auto [x, y] = Q.front();
Q.pop();
for (int i = 0; i < 2; ++i) {
int tx = dx[i] + x;
int ty = dy[i] + y;
if (tx < 0 || tx >= m || ty < 0|| ty >= n
|| vis[tx][ty]||get(tx)+get(ty) > k) continue;
Q.push(make_pair(tx, ty));
vis[tx][ty] = 1;
ans++;
}
}
return ans;
}
};
剑指 Offer 34. 二叉树中和为某一值的路径❤️
class Solution {
public:
vector<vector<int>>ret;
vector<int>path;
void dfs(TreeNode * root,int target)
{
if(root == nullptr) return;
path.emplace_back(root->val);
target -= root->val;
if(root->left == nullptr && root->right == nullptr && target == 0)
{
ret.emplace_back(path);
}
dfs(root->left,target);
dfs(root->right,target);
path.pop_back();
}
vector<vector<int>> pathSum(TreeNode* root, int target) {
if(root == nullptr) return {};
dfs(root,target);
return ret;
}
};
剑指 Offer 54. 二叉搜索树的第k大节点❤️
class Solution {
public:
priority_queue<int,vector<int>>q;
void PreInorder(TreeNode * root)
{
if(root == nullptr) return;
q.push(root->val);
PreInorder(root->left);
PreInorder(root->right);
}
int kthLargest(TreeNode* root, int k) {
PreInorder(root);
int maxi = -1e9;
while(k--)
{
maxi = q.top();
q.pop();
}
return maxi;
}
};
17. 电话号码的字母组合
class Solution {
char * str[10] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
public:
void dfs(string digits,vector<string>&v,int di,string conbina)
{
if(di == digits.size())
{
v.push_back(conbina);
return;
}
int num = digits[di] - '0';
string s = str[num];
for(auto ch : s)
{
dfs(digits,v,di + 1,conbina + ch);
}
}
vector<string> letterCombinations(string digits) {
vector<string>v;
if(digits.empty()) return v;
int di = 0;
string conbina;
dfs(digits,v,di,conbina);
return v;
}
};
剑指 Offer 36. 二叉搜索树与双向链表
class Solution {
public:
void dfs(Node * cur)
{
if(cur == nullptr) return;
dfs(cur->left);
if(head == nullptr)
{
head = tail = cur;
}
else
{
tail->right = cur;
cur->left = tail;
tail = cur;
}
dfs(cur->right);
}
Node* treeToDoublyList(Node* root)
{
if(root == nullptr) return nullptr;
dfs(root);
head->left = tail;
tail->right = head;
return head;
}
private:
Node * head = nullptr;
Node * tail = nullptr;
};
剑指 Offer 55 - I. 二叉树的深度
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root == nullptr) return 0;
int leftmax = maxDepth(root->left);
int rightmax = maxDepth(root->right);
return leftmax > rightmax ? leftmax + 1 : rightmax + 1;
}
};
剑指 Offer 55 - II. 平衡二叉树
class Solution {
public:
int maxDepth(TreeNode * root)
{
if(root == nullptr) return 0;
int leftmax = maxDepth(root->left);
int rightmax = maxDepth(root->right);
return leftmax > rightmax ? leftmax + 1 : rightmax + 1;
}
bool isBalanced(TreeNode* root)
{
if(root==NULL)
{
return true;
}
int leftmax = maxDepth(root->left);
int rightmax = maxDepth(root->right);
return abs(leftmax-rightmax)<2 && isBalanced(root->left) && isBalanced(root->right);
}
};
剑指 Offer 64. 求1+2+…+n
class Solution {
public:
int sumNums(int n) {
n && (n += sumNums(n - 1));
return n;
}
};
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
class Solution {
public:
vector<TreeNode*>GetPath(TreeNode * root,TreeNode *target)
{
vector<TreeNode*>ret;
while(root != target)
{
ret.push_back(root);
if(root->val > target->val)
{
root = root->left;
}
else
{
root = root->right;
}
}
ret.push_back(root);
return ret;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*>path_p = GetPath(root,p);
vector<TreeNode*>path_q = GetPath(root,q);
TreeNode * res = nullptr;
for(int i = 0; i < path_p.size() && i < path_q.size(); i++)
{
if(path_p[i] == path_q[i])
{
res = path_p[i];
}
else{
break;
}
}
return res;
}
};
剑指 Offer 68 - II. 二叉树的最近公共祖先
class Solution {
public:
bool GetPath(vector<TreeNode*>&path,TreeNode*root,TreeNode * target)
{
if(root == nullptr) return false;
if(root == target)
{
path.push_back(root);
return true;
}
path.push_back(root);
bool left1 = GetPath(path,root->left,target);
if(left1) return true;
bool right1 = GetPath(path,root->right,target);
if(right1) return true;
path.pop_back();
return false;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*>path_p;
vector<TreeNode*>path_q;
bool p1 = GetPath(path_p,root,p);
bool q1 = GetPath(path_q,root,q);
TreeNode * res = nullptr;
for(int i = 0; i < path_p.size() && i < path_q.size(); i++)
{
if(path_p[i] == path_q[i])
{
res = path_p[i];
}
else{
break;
}
}
return res;
}
};
剑指 Offer 37. 序列化二叉树❤️
class Codec {
public:
void rserialize(TreeNode * root,string & ret)
{
if(root == nullptr)
{
ret += "#,";
return;
}
ret += to_string(root->val);
ret += ",";
rserialize(root->left,ret);
rserialize(root->right,ret);
}
string serialize(TreeNode* root) {
string ret;
rserialize(root,ret);
return ret;
}
TreeNode* rdeserialize(list<string>&dateArray)
{
if(dateArray.front() == "#")
{
dateArray.erase(dateArray.begin());
return nullptr;
}
TreeNode * root = new TreeNode(stoi(dateArray.front()));
dateArray.erase(dateArray.begin());
root->left = rdeserialize(dateArray);
root->right = rdeserialize(dateArray);
return root;
}
TreeNode* deserialize(string data) {
list<string>dateArray;
string str;
for(auto& c : data)
{
if(c == ',')
{
dateArray.push_back(str);
str.clear();
}
else
{
str.push_back(c);
}
}
if(!str.empty())
{
dateArray.push_back(str);
str.clear();
}
return rdeserialize(dateArray);
}
};
剑指 Offer 38. 字符串的排列❤️
class Solution {
public:
unordered_map<string,int>hash;
void dfs(string s,vector<string>& ret,int len,string str,vector<int>&flag)
{
if(str.size() == len)
{
if(!hash.count(str))
{
ret.push_back(str);
hash.insert({str,1});
}
return;
}
for(int i = 0; i < s.size(); i++)
{
if(!flag[i])
{
flag[i] = true;
dfs(s,ret,len,str + s[i],flag);
flag[i] = false;
}
}
}
vector<string> permutation(string s) {
int len = s.size();
vector<string>ret;
vector<int>flag;
flag.resize(len);
string str;
dfs(s,ret,len,str,flag);
return ret;
}
};
剑指 Offer 17. 打印从1到最大的n位数
class Solution {
public:
vector<int> printNumbers(int n) {
vector<int>ret;
if(n == 0) return ret;
int k = 1;
while(n--)
{
k *= 10;
}
for(int i = 1; i < k; i++)
{
ret.push_back(i);
}
return ret;
}
};
剑指 Offer 51. 数组中的逆序对
class Solution {
public:
int merge(vector<int>&nums,int left,int right,vector<int>&tmp)
{
if(left >= right) return 0;
int mid = (left + right) >> 1;
int res = merge(nums,left,mid,tmp) + merge(nums,mid+1,right,tmp);
int k = 0,i = left,j = mid + 1;
while(i <= mid && j <= right)
{
if(nums[i] <= nums[j])
{
tmp[k++] = nums[i++];
}
else
{
tmp[k++] = nums[j++];
res += mid - i + 1;
}
}
while(i <= mid)
{
tmp[k++] = nums[i++];
}
while(j <= right)
{
tmp[k++] = nums[j++];
}
for(int i = left,j = 0; i <= right; i++, j++)
{
nums[i] = tmp[j];
}
return res;
}
int reversePairs(vector<int>& nums) {
if(nums.size() == 0) return 0;
vector<int>tmp;
int len = nums.size();
tmp.resize(len+1);
return merge(nums,0,len-1,tmp);
}
};
剑指 Offer 07. 重建二叉树
class Solution {
private:
unordered_map<int, int> hash;
public:
TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder,int& prei,
int in_begin,int in_end)
{
if(in_begin > in_end)
return nullptr;
TreeNode* root = new TreeNode(preorder[prei++]);
int root_size = hash[root->val];
root->left = _buildTree(preorder,inorder,prei,in_begin,root_size-1);
root->right = _buildTree(preorder,inorder,prei,root_size+1,in_end);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
for(int i = 0; i < inorder.size(); i++)
{
hash.insert({inorder[i],i});
}
int i = 0;
return _buildTree(preorder,inorder,i,0,inorder.size()-1);
}
};
剑指 Offer 16. 数值的整数次方
class Solution {
public:
double Pow(double x,long long n)
{
if(n == 0) return 1.0;
double y = Pow(x,n / 2);
return n % 2 == 0? y * y : y * y * x;
}
double myPow(double x, int n)
{
if(n == 0) return 1.0;
long long N = n;
return N >= 0 ? Pow(x,N) : 1 / Pow(x,-N);
}
};
剑指 Offer 45. 把数组排成最小的数❤️
class Solution {
public:
void quick_sort(vector<string>&str, int left, int right)
{
if(left >= right) return;
int i = left,j = right;
while(i < j)
{
while(i < j && str[j] + str[left] >= str[left] + str[j]) j--;
while(i < j && str[i] + str[left] <= str[left] + str[i]) i++;
if(i < j) swap(str[i],str[j]);
}
swap(str[left],str[j]);
quick_sort(str,left,j - 1);
quick_sort(str,j + 1,right);
}
string minNumber(vector<int>& nums) {
vector<string>str;
int len = nums.size();
for(int i = 0; i < len; i++)
{
str.push_back(to_string(nums[i]));
}
quick_sort(str,0,len-1);
string ret;
for(auto ch : str)
{
ret += ch;
}
return ret;
}
};
剑指 Offer 61. 扑克牌中的顺子
class Solution {
public:
bool isStraight(vector<int>& nums) {
int maxi = 0, mini = 14;
unordered_map<int,int>hash;
for(int i = 0; i < 5; i++)
{
if(nums[i] == 0) continue;
maxi = ::max(nums[i],maxi);
mini = ::min(nums[i],mini);
if(hash.count(nums[i]))
{
return false;
}
hash.insert({nums[i],i});
}
if(maxi - mini < 5) return true;
return false;
}
};
剑指 Offer 40. 最小的k个数
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
vector<int>ret;
priority_queue<int,vector<int>,greater<int>>q;
for(auto ch : arr)
{
q.push(ch);
}
while(k--)
{
int top = q.top();
q.pop();
ret.push_back(top);
}
return ret;
}
};
150. 逆波兰表达式求值
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int>st;
for(auto& ch : tokens)
{
if(ch == "+" || ch == "-" || ch == "*" || ch == "/")
{
int right = st.top();
st.pop();
int left = st.top();
st.pop();
char str = ch[0];
int num;
switch(str)
{
case '+':
num = left + right;
st.push(num);
break;
case '-':
num = left - right;
st.push(num);
break;
case '*':
num = left * right;
st.push(num);
break;
case '/':
num = left / right;
st.push(num);
break;
}
}
else
{
st.push(stoi(ch));
}
}
return st.top();
}
};
剑指 Offer 10- I. 斐波那契数列
class Solution {
public:
int fib(int n) {
long long * dp = new long long [110];
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= n; i++)
{
dp[i] = (dp[i - 1] + dp[i - 2])%(1000000007);
}
return(int)dp[n];
}
};
剑指 Offer 10- II. 青蛙跳台阶问题
class Solution {
public:
int numWays(int n) {
long long * dp = new long long [110];
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i <= n; i++)
{
dp[i] = (dp[i - 1] + dp[i - 2])%(1000000007);
}
return(int)dp[n];
}
};
剑指 Offer 63. 股票的最大利润❤️
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
int mini = 0x3f3f3f3f;
int maxi = 0;
for(auto price : prices)
{
maxi = max(maxi,price - mini);
mini = min(mini,price);
}
return maxi;
}
};
剑指 Offer 42. 连续子数组的最大和
class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int>dp(nums.size(),0);
dp[0] = nums[0];
for(int i = 1; i < nums.size(); i++)
{
dp[i] = max(dp[i - 1] + nums[i],nums[i]);
}
int maxi = -0x3f3f3f3f;
for(int i = 0; i < nums.size(); i++)
{
maxi = max(dp[i],maxi);
}
return maxi;
}
};
剑指 Offer 47. 礼物的最大价值❤️
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
vector<vector<int>> dp(m, vector<int>(n));
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
if(i > 0)
{
dp[i][j] = max(dp[i][j],dp[i-1][j]);
}
if(j > 0)
{
dp[i][j] = max(dp[i][j],dp[i][j -1]);
}
dp[i][j] += grid[i][j];
}
}
return dp[m - 1][n - 1];
}
};
剑指 Offer 46. 把数字翻译成字符串
class Solution {
public:
int translateNum(int num) {
string str = to_string(num);
int len = str.size();
vector<int>dp(len+1,0);
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i <= len; i++)
{
string sub = str.substr(i - 2,2);
if(sub <= "25" && sub >= "10")
{
dp[i] = dp[i - 1] + dp[i - 2];
}
else
{
dp[i] = dp[i - 1];
}
}
return dp[len];
}
};
剑指 Offer 64. 求1+2+…+n
class Sum
{
public:
Sum()
{
_sum += _i;
_i++;
}
static int get()
{
return _sum;
}
void Destroy()
{
_sum = 0;
_i = 1;
}
private:
static int _i;
static int _sum;
};
int Sum::_sum = 0;
int Sum::_i = 1;
int func(int n)
{
Sum *s = new Sum[n];
int ret = s->get();
s->Destroy();
return ret;
}
class Solution {
public:
int sumNums(int n) {
return func(n);
}
};
剑指 Offer 48. 最长不含重复字符的子字符串❤️
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int len = s.size();
if(len == 0) return 0;
if(len == 1) return 1;
vector<int>dp(len,0);
dp[0] = 1;
int maxlen = 0;
int tmp = 0;
for(int i = 1; i < len; i++)
{
int j = i - 1;
while(j >= 0 && s[i] != s[j]) j--;
if(dp[i-1] < i - j) dp[i] = dp[i-1] + 1;
else dp[i] = i - j;
if(dp[i] > maxlen) maxlen = dp[i];
}
return maxlen;
}
};
264. 丑数 II
class Solution {
public:
int nthUglyNumber(int n) {
priority_queue<double,vector<double>,greater<double>>q;
double ans = 1;
for(int i = 1; i < n; i++)
{
q.push(ans*2);
q.push(ans*3);
q.push(ans*5);
ans = q.top();
q.pop();
while(!q.empty() && q.top() == ans) q.pop();
}
return ans;
}
};
剑指 Offer 15. 二进制中1的个数
class Solution {
public:
int hammingWeight(uint32_t n) {
int count = 0;
while(n)
{
n = n & (n - 1);
count++;
}
return count;
}
};
剑指 Offer 65. 不用加减乘除做加法
class Solution {
public:
int add(int a, int b) {
while (b != 0) {
unsigned int carry = (unsigned int)(a & b) << 1;
a = a ^ b;
b = carry;
}
return a;
}
};
剑指 Offer 56 - I. 数组中数字出现的次数
class Solution {
public:
vector<int> GetNum(vector<int>&nums, int sz)
{
vector<int>ret;
int k = 0;
for(int i = 0; i < 31; i++)
{
if((sz >> i) & 1 == 1)
{
k = i;
break;
}
}
int a = 0, b = 0;
for(int i = 0; i < nums.size(); i++)
{
if(((nums[i] >> k) & 1) == 0)
{
a ^= nums[i];
}
else
{
b ^= nums[i];
}
}
ret.push_back(a);
ret.push_back(b);
return ret;
}
vector<int> singleNumbers(vector<int>& nums)
{
vector<int>ret;
int sz = 0;
for(int i = 0; i < nums.size(); i++)
{
sz ^= nums[i];
}
return GetNum(nums,sz);
}
};
剑指 Offer 56 - II. 数组中数字出现的次数 II
class Solution {
public:
int singleNumber(vector<int>& nums) {
if(nums.size() == 1) return nums[0];
sort(nums.begin(),nums.end());
for(int i = 1; i < nums.size()-1; i++)
{
if(nums[i] != nums[i - 1] && nums[i] != nums[i + 1])
{
return nums[i];
}
}
if(nums[0] != nums[1]) return nums[0];
return nums[nums.size() - 1];
}
};
剑指 Offer 39. 数组中出现次数超过一半的数字
class Solution {
public:
int majorityElement(vector<int>& nums) {
if(nums.size() == 1) return nums[0];
sort(nums.begin(),nums.end());
int count = 1;
int sz = nums[0];
int len = nums.size() / 2;
for(int i = 1; i < nums.size(); i++)
{
if(count > len)
{
break;
}
if(sz == nums[i])
{
count++;
}
else
{
sz = nums[i];
count = 1;
}
}
return sz;
}
};
剑指 Offer 66. 构建乘积数组
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
vector<int>ret;
if(a.size() == 0) return ret;
int len = a.size();
vector<int>left(len,0);
vector<int>right(len,0);
left[0] = 1;
for(int i = 1; i < len; i++)
{
left[i] = a[i - 1] * left[i - 1];
}
right[len - 1] = 1;
for(int i = len - 2; i >= 0; i--)
{
right[i] = a[i + 1] * right[i + 1];
}
for(int i = 0; i < len; i++)
{
ret.push_back(left[i] * right[i]);
}
return ret;
}
};
剑指 Offer 57 - II. 和为s的连续正数序列❤️
class Solution {
public:
vector<vector<int>> findContinuousSequence(int target) {
vector<vector<int>>ret;
int i = 1;
int j = 1;
int sum =0;
while(i <= target / 2)
{
if(sum > target)
{
sum -= i;
i++;
}
else if(sum < target)
{
sum += j;
j++;
}
else
{
vector<int>res;
for(int k = i; k < j; k++)
{
res.push_back(k);
}
ret.push_back(res);
sum -= i;
i++;
}
}
return ret;
}
};
剑指 Offer 62. 圆圈中最后剩下的数字
class Solution {
public:
int lastRemaining(int n, int m) {
int pos = 0;
for(int i = 2; i <= n; i++) {
pos = (pos + m) % i;
}
return pos;
}
};
剑指 Offer 44. 数字序列中某一位的数字❤️
class Solution {
public:
int findNthDigit(int n) {
int i=1;
while(n > 9*pow(10,i-1) *i)
{
n = n - 9*pow(10,i-1) *i;
i++;
}
int min_num = pow(10,i-1);
int cur_num = min_num + (n-1)/i;
int cur_bit = (n-1)%i;
string s = to_string(cur_num);
return s[cur_bit]-'0';
}
};
剑指 Offer 33. 二叉搜索树的后序遍历序列❤️
class Solution {
public:
bool PostOrder(vector<int>& postorder, int start, int end)
{
if(start >= end) return true;
int index = start;
while(postorder[index] < postorder[end]) index++;
int min_index = index;
while(postorder[index] > postorder[end]) index++;
bool left = PostOrder(postorder,start,min_index - 1);
bool right = PostOrder(postorder,min_index,end-1);
return index == end && left && right;
}
bool verifyPostorder(vector<int>& postorder) {
return PostOrder(postorder, 0, postorder.size()-1);
}
};