力扣-剑指offer所有题
Posted 行码阁119
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣-剑指offer所有题相关的知识,希望对你有一定的参考价值。
第1天 栈基本
1.1包含min函数的栈
剑指 Offer 30. 包含min函数的栈https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
示例:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.
class MinStack
public:
/** initialize your data structure here. */
stack<int> s1;
stack<int> s2;
MinStack()
void push(int x)
s1.push(x);
if(s2.empty() || s2.top() >= x)
s2.push(x);
void pop()
if(s1.empty()) return;
int temp = s1.top();
s1.pop();
if(s2.top() == temp)
s2.pop();
int top()
return s1.top();
int min()
return s2.top();
;
class MinStack
public:
/** initialize your data structure here. */
stack<int> s1;
stack<int> s2;
MinStack()
void push(int x)
s1.push(x);
if(s2.empty() || s2.top() >= x)
s2.push(x);
void pop()
if(s1.empty()) return;
int temp = s1.top();
s1.pop();
if(s2.top() == temp)
s2.pop();
int top()
return s1.top();
int min()
return s2.top();
;
1.2 用两个栈实现队列
剑指 Offer 09. 用两个栈实现队列https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.min(); --> 返回 -2.
第2天 链表基本
2.1 从尾到头打印链表
剑指 Offer 06. 从尾到头打印链表https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/
class Solution
public:
vector<int> result;
void recur(ListNode* cur)
if(cur == NULL )
return;
recur(cur->next);
result.push_back(cur->val);
return;
vector<int> reversePrint(ListNode* head)
recur(head);
return result;
;
也可以利用栈的先进后出的性质
2.2 反转链表
剑指 Offer 24. 反转链表https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/
class Solution
public:
ListNode* reverseList(ListNode* head)
ListNode* pre = NULL;
ListNode* cur = head;
while(cur)
ListNode* temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
return pre;
;
剑指 Offer 35. 复杂链表的复制https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/
class Solution
public:
Node* copyRandomList(Node* head)
unordered_map<Node*, Node*> mp;
Node* cur = head;
while(cur)
mp[cur] = new Node(cur->val);
cur = cur->next;
cur = head;
while(cur)
mp[cur]->next = mp[cur->next];
mp[cur]->random = mp[cur->random];
cur = cur->next;
return mp[head];
;
第3天 字符串基本
3.1 替换空格
剑指 Offer 05. 替换空格https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/
请实现一个函数,把字符串 s
中的每个空格替换成"%20"。
示例 1:
输入:s = "We are happy."
输出:"We%20are%20happy."
class Solution
public:
string replaceSpace(string s)
int n = s.size();
int temp = n;
for(int i = 0; i < s.size(); i++)
if(s[i] == ' ')
temp += 2;
s.resize(temp);
int j = n - 1;
for(int i = temp - 1; i >= 0; i--)
if(s[j] != ' ')
s[i] = s[j--];
else
s[i--] = '0';
s[i--] = '2';
s[i] = '%';
j--;
return s;
;
看答案有一种很巧妙地用法,只需要遍历一次
利用c++的引用
class Solution
public:
string replaceSpace(string s) //字符数组
string array; //存储结果
for(auto &c : s) //遍历原字符串
if(c == ' ')
array.push_back('%');
array.push_back('2');
array.push_back('0');
else
array.push_back(c);
return array;
;
3.3 左旋转字符串
剑指 Offer 58 - II. 左旋转字符串https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/
class Solution
public:
string reverseLeftWords(string s, int n)
reverse(s.begin(), s.begin() + n);
reverse(s.begin() + n, s.end());
reverse(s.begin(), s.end());
return s;
;
第4天 查找算法 基本
4.1 数组中重复的数字
剑指 Offer 03. 数组中重复的数字https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
class Solution
public:
int findRepeatNumber(vector<int>& nums)
unordered_map<int, int> map;
for(int num : nums)
map[num]++;
if(map.count(num) && map[num] > 1)
return num;
return 0;
;
由于nums数组中的元素为(0-n-1),那么可以充分利用nums[i] - 1的大小来判断其是否出现两次,具体实现看代码
class Solution
public:
//时间复杂度为O(n),空间复杂度为O(1)
int findRepeatNumber(vector<int>& nums)
for(int i = 0; i < nums.size(); i++)
nums[i] = nums[i] + 1;
int n = nums.size();
for(int i = 0; i < nums.size(); i++)
int temp = (nums[i] - 1) % n;
if(nums[temp] >= n) return (nums[i] - 1) % n;
nums[temp] += n;
return 0;
;
4.2 在排序数组中查找数字
统计一个数字在排序数组中出现的次数。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: 0
class Solution
public:
int search(vector<int>& nums, int target)
int l = 0;
int r = nums.size() - 1;
while(l <= r)
int mid = l + (r - l) / 2;
if(nums[mid] < target)
l = mid + 1;
else
r = mid - 1;
int left = l;
l = 0;
r = nums.size() - 1;
while(l <= r)
int mid = l + (r - l) / 2;
if(nums[mid] <= target)
l = mid + 1;
else
r = mid - 1;
int right = r;
return right - left + 1;
;
4.3 在0-n-1中找缺失的数字
剑指 Offer 53 - II. 0~n-1中缺失的数字https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof/
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
示例 1:
输入: [0,1,3]
输出: 2
示例 2:
输入: [0,1,2,3,4,5,6,7,9]
输出: 8
class Solution
public:
int missingNumber(vector<int>& nums)
int l = 0;
int r = nums.size() - 1;
while(l <= r)
int mid = l + (r - l) / 2;
if(nums[mid] == mid)
l = mid + 1;
else
r = mid - 1;
return r + 1;
;
第5天 查找
5.1 在二维数组中查找
剑指 Offer 04. 二维数组中的查找https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
class Solution
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target)
if(matrix.size() == 0 || matrix[0].size() == 0) return false;
for(int i = 0; i < matrix.size(); i++)
if(matrix[i][0] <= target)
int l = 0;
int r = matrix[i].size() - 1;
while(l <= r)
int mid = l + (r - l) / 2;
if(matrix[i][mid] == target)
return true;
else if(matrix[i][mid] < target)
l = mid + 1;
else
r = mid - 1;
return false;
;
官方时间复杂度为O(n + m)
class Solution
public boolean findNumberIn2DArray(int[][] matrix, int target)
if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
return false;
int rows = matrix.length, columns = matrix[0].length;
int row = 0, column = columns - 1;
while (row < rows && column >= 0)
int num = matrix[row][column];
if (num == target)
return true;
else if (num > target)
column--;
else
row++;
return false;
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/solution/mian-shi-ti-04-er-wei-shu-zu-zhong-de-cha-zhao-b-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
5.2 旋转数组的最小数组
剑指 Offer 11. 旋转数组的最小数字https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为1。
示例 1:
输入:[3,4,5,1,2]
输出:1
示例 2:
输入:[2,2,2,0,1]
输出:0
class Solution
public:
int minArray(vector<int>& numbers)
int l = 0;
int r = numbers.size() - 1;
while(l < r)
int mid = l + (r - l) / 2;
if(numbers[mid] < numbers[r])
r = mid;
else if(numbers[mid] > numbers[r])
l = mid + 1;
else
r = r - 1;
return numbers[l];
;
5.3 第一个只出现一次的字符
面试题50. 第一个只出现一次的字符https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。
示例 1:
输入:s = "abaccdeff"
输出:'b'
示例 2:
输入:s = ""
输出:' '
class Solution
public:
char firstUniqChar(string s)
unordered_map<int, int> mp;
for(int i = 0; i < s.size(); i++)
mp[s[i]]++;
for(int i = 0; i < s.size(); i++)
if(mp[s[i]] == 1)
return s[i];
return ' ';
;
class Solution
public:
char firstUniqChar(string s)
unordered_map<char, int> position;
int n = s.size();
for (int i = 0; i < n; ++i)
if (position.count(s[i]))
position[s[i]] = -1;
else
position[s[i]] = i;
int first = n;
for (auto [_, pos]: position)
if (pos != -1 && pos < first)
first = pos;
return first == n ? ' ' : s[first];
;
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/solution/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-by-3zqv5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
第6天 二叉树
6.1 从上到下打印出二叉树
面试题32 - I. 从上到下打印二叉树https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/
class Solution
public:
vector<int> levelOrder(TreeNode* root)
queue<TreeNode*> que;
vector<int> result;
if(!root)
return result;
que.push(root);
while(!que.empty())
int len = que.size();
while(len--)
auto t = que.front();
que.pop();
result.push_back(t->val);
if(t->left)
que.push(t->left);
if(t->right)
que.push(t->right);
return result;
;
6.2 从上到下打印出二叉树 II
class Solution
public:
vector<vector<int>> levelOrder(TreeNode* root)
queue<TreeNode*> que;
vector<vector<int>> result;
if(!root)
return result;
que.push(root);
while(!que.empty())
int len = que.size();
vector<int> path(len);
while(len--)
auto t = que.front();
que.pop();
path.push_back(t->val);
if(t->left)
que.push(t->left);
if(t->right)
que.push(t->right);
result.push_back(path);
return result;
;
class Solution
public:
vector<vector<int>> levelOrder(TreeNode* root)
queue<TreeNode*> que;
vector<vector<int>> result;
if(!root)
return result;
que.push(root);
while(!que.empty())
int len = que.size();
vector<int> path(len);
for(int i = 0; i < len; i++)
auto t = que.front();
que.pop();
int j = i;
if(result.size() % 2 != 0)
j = len - i - 1;
path[j] = t->val;
if(t->left)
que.push(t->left);
if(t->right)
que.push(t->right);
result.push_back(path);
return result;
;
第7天 二叉树
7.1 树的子结构
剑指 Offer 26. 树的子结构https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/
输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
例如:
给定的树 A:
3
/ \\
4 5
/ \\
1 2
给定的树 B:
4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。
class Solution
public:
bool compare(TreeNode* A, TreeNode* B)
if( A == NULL && B == NULL) return true;
if(A == NULL && B != NULL) return false;
if(A != NULL && B == NULL) return true;
if(A->val != B->val) return false;
return compare(A->left, B->left) && compare(A->right, B->right);
bool isSubStructure(TreeNode* A, TreeNode* B)
if(A == NULL) return false;
if(B == NULL) return false;
return compare(A, B) || (isSubStructure(A->left, B) || isSubStructure(A->right, B));
;
7.2 二叉树的镜像
剑指 Offer 27. 二叉树的镜像https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
例如输入:
4
/ \\
2 7
/ \\ / \\
1 3 6 9
镜像输出:
4
/ \\
7 2
/ \\ / \\
9 6 3 1
class Solution
public:
TreeNode* mirrorTree(TreeNode* root)
if(root == NULL) return root;
swap(root->left, root->right);
mirrorTree(root->left);
mirrorTree(root->right);
return root;
;
7.3 对称的二叉树
剑指 Offer 28. 对称的二叉树https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \\
2 2
/ \\ / \\
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \\
2 2
\\ \\
3 3
class Solution
public:
bool compare(TreeNode* lroot, TreeNode* rroot)
if(lroot && !rroot)
return false;
if(!lroot && rroot)
return false;
if(!lroot && !rroot)
return true;
if(lroot->val != rroot->val)
return false;
bool t1 = compare(lroot->left, rroot->right);
bool t2 = compare(lroot->right, rroot->left);
return t1 && t2;
bool isSymmetric(TreeNode* root)
if(!root) return true;
return compare(root->left, root->right);
;
第8天 动态规划
8.1 菲波那切数列
剑指 Offer 10- I. 斐波那契数列https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/
class Solution
public:
int fib(int n)
if(n < 2) return n;
vector<int> dp(3, 0);
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= n; i++)
dp[2] = (dp[0] + dp[1]) % 1000000007;
dp[0] = dp[1];
dp[1] = dp[2];
return dp[2];
;
8.2 青蛙跳台
剑指 Offer 10- II. 青蛙跳台阶问题https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/
class Solution
public:
int numWays(int n)
if(n < 2) return 1;
vector<int> dp(3, 0);
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i <= n; i++)
dp[2] = (dp[0] + dp[1]) % 1000000007;
dp[0] = dp[1];
dp[1] = dp[2];
return dp[2];
;
8.3 股票最大利润
剑指 Offer 63. 股票的最大利润https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof/
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?
示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
class Solution
public:
int maxProfit(vector<int>& prices)
int n = prices.size();
if( n == 0)
return 0;
vector<vector<int>> dp(2, vector(n, 0));
dp[0][0] = - prices[0];
dp[1][0] = 0;
int mmax = 0;
for(int i = 1; i < prices.size(); i++)
dp[0][i] = max(dp[0][i - 1] ,-prices[i]);
dp[1][i] = max(dp[1][i - 1], dp[0][i - 1] + prices[i]);
mmax = max(dp[1][i], mmax);
return mmax;
;
第9天 动态规划 中等
9.1 把数字翻译为字符串
剑指 Offer 46. 把数字翻译成字符串https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
class Solution
public:
int translateNum(int num)
string mys = to_string(num);
vector<int> dp(mys.size(), 0);
dp[0] = 1;
for(int i = 1; i < mys.size(); i++)
if (mys[i - 1] == '0' || mys[i - 1] > '2' || (mys[i - 1] == '2' && mys[i] > '5'))
dp[i] = dp[i - 1];
else if(i > 1)
dp[i] = d[i - 1] + dp[i - 2] + 1;
else
dp[i] = dp[i - 1] + 1;
return dp[mys.size() - 1];
;
class Solution
public:
int translateNum(int num)
string str = to_string(num);
vector<int> dp(str.size() + 1, 1);
dp[0] = 1;
for(int i = 1; i < str.size() + 1; i++)
if(str[i - 1] >= '6')
if(i - 2 >= 0 && str[i - 2] == '1')
dp[i] = dp[i - 1] + dp[i - 2];
else if(i - 2 >= 0 && str[i - 2] == '0')
dp[i] = dp[i - 1];
else dp[i] = dp[i - 1];
else if(str[i - 1] <= '5')
if(i - 2 >= 0 && str[i - 2] <= '2' && str[i - 2] > '0')
dp[i] = dp[i - 1] + dp[i - 2];
else if(i - 2 >= 0 && str[i - 2] == '0')
dp[i] = dp[i - 1];
else dp[i] = dp[i - 1];
return dp[str.size()];
;
class Solution
public:
int translateNum(int num)
string mys = to_string(num);
if(mys.size() == 1) return 1;
vector<int> dp(3, 0);
dp[0] = 1;
dp[1] = 1;
for(int i = 1; i < mys.size(); i++)
if (mys[i - 1] == '0' || mys[i - 1] > '2' || (mys[i - 1] == '2' && mys[i] > '5'))
dp[2] = dp[1];
else if(i > 1)
dp[2] = dp[0] + dp[1];
else
dp[2] = dp[1] + 1;
dp[0] = dp[1];
dp[1] = dp[2];
return dp[2];
;
官方代码:
class Solution
public:
int translateNum(int num)
string src = to_string(num);
int p = 0, q = 0, r = 1;
for (int i = 0; i < src.size(); ++i)
p = q;
q = r;
r = 0;
r += q;
if (i == 0)
continue;
auto pre = src.substr(i - 1, 2);
if (pre <= "25" && pre >= "10")
r += p;
return r;
;
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/solution/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-by-leetcode-sol/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
9.2 最长含不重复字符的子字符串
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
class Solution
public:
int lengthOfLongestSubstring(string s)
unordered_map<char, int> map;;
int l = 0; int r = 0;
int len = 0;
while(r < s.size())
map[s[r]]++;
while(map.count(s[r]) && map[s[r]] > 1)
map[s[l]]--;
l++;
if(map[s[r]] == 1)
len = max(len, r - l + 1);
r++;
return len;
;
class Solution
public:
int lengthOfLongestSubstring(string s)
if(s.size() < 2) return s.size();
vector<int> dp(s.size(), 1);
unordered_map<char, int> record;
int mmax = 1;
record[s[0]] = 0;
for(int i = 1; i < s.size(); i++)
if(!record.count(s[i]))
dp[i] = dp[i - 1] + 1;
else
int j = record[s[i]];
if(dp[i - 1] >= i - j)
dp[i] = i - j;
else
dp[i] = dp[i - 1] + 1;
mmax = max(mmax, dp[i]);
record[s[i]] = i;
return mmax;
;
20220506-复习
class Solution
public:
int lengthOfLongestSubstring(string s)
unordered_map<char, int> mp;
if(s.size() == 0)
return 0;
int l = 0;
int r = 0;
int count = 1;
while(r < s.size())
if(!mp.count(s[r]) || mp[s[r]] == 0)
mp[s[r]]++;
else
count = max(count, r - l );
while(l < r && (s[l] != s[r]))
mp[s[l]] = 0;
l++;
mp[s[l++]] = 0;
mp[s[r]]++;
r++;
count = max(count, r - l );
return count;
;
第 15 天 回溯
15.1 机器人运动的范围
剑指 Offer 13. 机器人的运动范围https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/
地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
示例 1:
输入:m = 2, n = 3, k = 1
输出:3
示例 2:
输入:m = 3, n = 1, k = 0
输出:1
class Solution
public:
int addNum(int x, int y)
int sum = 0;
while(x != 0)
sum += x % 10;
x = x / 10;
while(y != 0)
sum += y % 10;
y = y / 10;
return sum;
const int dist[4][2] = -1,0, 1, 0, 0, -1, 0, 1;
int movingCount(int m, int n, int k)
int nums = 1;
vector<vector<int>> visited(m, vector(n, 0));
visited[0][0] = 1;
queue<pair<int, int>> que;
que.push(0,0);
while(!que.empty())
int size = que.size();
while(size--)
auto [i, j] = que.front();
que.pop();
for(int t = 0; t < 4; t++)
int dx = i + dist[t][0];
int dy = j + dist[t][1];
if(dx >= 0 && dx < m && dy >=0 && dy < n && visited[dx][dy] == 0 )
if(addNum(dx, dy) <= k)
nums++;
visited[dx][dy] = 1;
que.push(dx, dy);
return nums;
;
class Solution
public:
int addNum(int x, int y)
int sum = 0;
while(x != 0)
sum += x % 10;
x = x / 10;
while(y != 0)
sum += y % 10;
y = y / 10;
return sum;
const int dist[4][2] = -1,0, 1, 0, 0, -1, 0, 1;
int nums = 0;
void dfs(int m, int n, int t, int i, int j, vector<vector<int>> &visited)
if(i == m || j == n)
return;
for(int k = 0; k < 4; k++)
int dx = i + dist[k][0];
int dy = j + dist[k][1];
if(dx >= 0 && dx < m && dy >=0 && dy < n && visited[dx][dy] == 0 )
if(addNum(dx, dy) <= t)
nums++;
visited[dx][dy] = 1;
dfs(m, n, t, dx, dy, visited);
int movingCount(int m, int n, int k)
vector<vector<int>> visited(m, vector(n, 0));
if(addNum(0, 0) <= k)
visited[0][0] = 1;
nums++;
dfs( m, n, k, 0, 0, visited);
return nums;
;
15.2 二叉树中和为某一值的路径
给你二叉树的根节点 root
和一个整数目标和 targetSum
,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
class Solution
public:
vector<vector<int>> result;
vector<int> path;
int sum = 0;
void dfs(TreeNode* root, int target)
if(root == NULL)
return;
sum += root->val;
path.push_back(root->val);
if(sum == target && !root->left && !root->right)
result.push_back(path);
sum -= root->val;
path.pop_back();
return;
dfs(root->left, target);
dfs(root->right, target);
sum -= root->val;
path.pop_back();
vector<vector<int>> pathSum(TreeNode* root, int target)
dfs(root, target);
return result;
;
15.3 二叉搜索树的第k大节点
剑指 Offer 54. 二叉搜索树的第k大节点https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/
class Solution
public:
int result = 0;
void midSerach(TreeNode* root, int &k)
if(root == NULL)
return;
midSerach(root->right, k);
k--;
if(k == 0)
result = root->val;
return;
midSerach(root->left, k);
return;
int kthLargest(TreeNode* root, int k)
midSerach(root, k);
return result;
;
class Solution
public:
int kthLargest(TreeNode* root, int k)
stack<TreeNode*> st;
TreeNode *cur = root;
while(cur != NULL || !st.empty())
if(cur != NULL)
st.push(cur);
cur = cur->right;
else
auto t = st.top();
st.pop();
k--;
if(k == 0)
return t->val;
if(t->left)
cur = t->left;
return 0;
;
20220610
class Solution
public:
int result = INT32_MAX;
void midbank(TreeNode* root, int& k)
if(root == NULL)
return;
midbank(root->right, k);
k--;
if(k == 0)
result = root->val;
if(result != INT32_MAX)
return;
midbank(root->left, k);
int kthLargest(TreeNode* root, int k)
midbank(root, k);
return result;
;
15.4 二插收缩树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
class Solution
public:
Node * pre = NULL;
Node * end;
Node * head;
void midSearch(Node* root)
if(root == NULL)
return;
Node * temp = root->right;
midSearch(root->left);
if(pre == NULL)
pre = root;
head = root;
else
pre->right = root;
root->left = pre;
pre = root;
midSearch(temp);
Node* treeToDoublyList(Node* root)
if(root == NULL) return head;
midSearch(root);
head->left = pre;
pre->right = head;
return head;
;
第16天 数组
16.1 把数组排成最小的数
剑指 Offer 45. 把数组排成最小的数https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
示例 1:
输入: [10,2]
输出: "102"
示例 2:
输入: [3,30,34,5,9]
输出: "3033459"
class Solution
public:
void quicksort(vector<int>& nums, int l, int r)
if(l >= r)
return;
int temp = nums[l];
int right = r;
int i = l;
while(i < r)
while(i < r && (to_string(nums[r]) + to_string(temp) > to_string(temp) + to_string(nums[r])))
r--;
if(i < r)
nums[i++] = nums[r];
while(i < r && (to_string(nums[i]) + to_string(temp) <= to_string(temp) + to_string(nums[i])))
i++;
if(i < r)
nums[r--] = nums[i];
nums[i] = temp;
quicksort(nums, i + 1, right);
quicksort(nums, l, i - 1);
string minNumber(vector<int>& nums)
string s;
quicksort(nums, 0, nums.size() - 1);
for(int i = 0; i < nums.size(); i++)
s += to_string(nums[i]);
return s;
;
class Solution
public:
static bool mcompare(const string& x, const string& y)
return x + y < y + x;
string minNumber(vector<int>& nums)
vector<string> str;
for(int i = 0; i < nums.size(); i++)
str.push_back(to_string(nums[i]));
sort(str.begin(), str.end(), mcompare);
string res;
for(int i = 0; i < str.size(); i++)
res += str[i];
return res;
;
16.2 扑克牌中的顺子
剑指 Offer 61. 扑克牌中的顺子https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/
从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
示例 1:
输入: [1,2,3,4,5]
输出: True
示例 2:
输入: [0,0,1,2,5]
输出: True
class Solution
public:
void mergeSort(vector<int>& nums, vector<int>& temp, int l, int r)
if(l >= r)
return;
int mid = l + (r - l) / 2;
mergeSort(nums, temp, l, mid);
mergeSort(nums, temp, mid + 1, r);
mysort(nums, temp, l, r);
return;
void mysort(vector<int>& nums, vector<int>& temp, int l, int r)
int mid = l + (r - l) / 2;
int t = mid + 1;
for(int i = l; i <= r; i++)
if(t > r )
temp[i] = nums[l++];
else if(l > mid)
temp[i] = nums[t++];
else if(nums[l] < nums[t])
temp[i] = nums[l++];
else if(nums[l] >= nums[t])
temp[i] = nums[t++];
nums = temp;
bool isStraight(vector<int>& nums)
vector<int> temp(nums);
mergeSort(nums, temp, 0, nums.size() - 1);
int count = 0;
for(int i = 0; i < nums.size(); i++)
if(nums[i] == 0)
count++;
if(i > 0 && nums[i] != nums[i - 1] + 1 && nums[i - 1] != 0)
int t = nums[i] - nums[i - 1] - 1;
if(count < t || nums[i] == nums[i - 1])
return false;
count = count - t;
return true;
;
class Solution
public:
bool isStraight(vector<int>& nums)
sort(nums.begin(), nums.end());
int count = 0;
for(int i = 0; i < nums.size(); i++)
if(nums[i] == 0) count++;
if(i > 0 && nums[i - 1] != 0)
int arr = nums[i] - nums[i - 1];
if(arr > 1)
count = count + 1 - arr;
else if(arr == 0) return false;
if(count < 0) return false;
return true;
;
第17天
17.1 最小的k个数
剑指 Offer 40. 最小的k个数https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/
输入整数数组 arr
,找出其中最小的 k
个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
示例 1:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]
示例 2:
输入:arr = [0,1,2,1], k = 1
输出:[0]
class Solution
public:
vector<int> getLeastNumbers(vector<int>& arr, int k)
priority_queue<int, vector<int>, less<int>> que;
int i = 0;
for(; i < k; i++)
que.push(arr[i]);
for(; i < arr.size(); i++)
que.push(arr[i]);
que.pop();
vector<int> result;
while(!que.empty())
result.push_back(que.top());
que.pop();
return result;
;
class Solution
public:
vector<int> getLeastNumbers(vector<int>& arr, int k)
vector<int> vec(k, 0);
sort(arr.begin(), arr.end());
for (int i = 0; i < k; ++i)
vec[i] = arr[i];
return vec;
;
17.2 数据流的中位数
剑指 Offer 41. 数据流中的中位数https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/
class MedianFinder
public:
class mycompare
public:
bool operator()(const int& a, const int &b)
return a > b;
;
/** initialize your data structure here. */
priority_queue<int, vector<int>> myqB;
priority_queue<int, vector<int>, mycompare> myqA;
MedianFinder()
void addNum(int num)
if(myqB.size() == myqA.size())
myqB.push(num);
myqA.push(myqB.top());
myqB.pop();
else
myqA.push(num);
myqB.push(myqA.top());
myqA.pop();
double findMedian()
double t;
if((myqB.size() + myqA.size()) % 2 ==0)
t = double((myqA.top() + myqB.top())) / 2;
else t = myqA.top();
return t;
;
第18天 二叉树
18.1平衡二叉树
剑指 Offer 55 - II. 平衡二叉树https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
3
/ \\
9 20
/ \\
15 7
返回 true 。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
1
/ \\
2 2
/ \\
3 3
/ \\
4 4
返回 false 。
class Solution
public:
int recur(TreeNode *root)
if(root == NULL) return 0;
int left = recur(root->left);
int right = recur(root->right);
if(left == -1 || right == -1) return -1;
if(abs(left - right) > 1) return -1;
return max(left, right) + 1;
bool isBalanced(TreeNode* root)
int t = recur(root);
if(t != -1) return true;
return false;
;
18.2 二叉树的深度
剑指 Offer 55 - I. 二叉树的深度https://leetcode-cn.com/problems/er-cha-shu 以上是关于力扣-剑指offer所有题的主要内容,如果未能解决你的问题,请参考以下文章