leetcode剑指offer合集+题解
Posted hesorchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode剑指offer合集+题解相关的知识,希望对你有一定的参考价值。
目录
- 一、用两个栈实现队列
- 二、包含min函数的栈
- 三、从尾到头打印链表
- 四、反转链表
- 五、复杂链表的复制
- 六、替换空格
- 七、左旋转字符串
- 八、数组中重复的数字
- 九、I. 在排序数组中查找数字
- 十、II. 0~n-1中缺失的数字
- 十一、二维数组中的查找
- 十二、旋转数组的最小数字
- 十三、第一个只出现一次的字符
- 十四、I. 从上到下打印二叉树
- 十五、从上到下打印二叉树 II
- 十六、从上到下打印二叉树 III
- 十七、树的子结构
- 十八、二叉树的镜像
- 十九、对称的二叉树
- 二十、斐波那契数列
- 二十一、青蛙跳台阶问题
- 二十二、股票的最大利润
- 二十三、连续子数组的最大和
- 二十四、礼物的最大价值
- 二十五、把数字翻译成字符串
- 二十六、最长不含重复字符的子字符串
- 二十七、删除链表的节点
- 二十八、链表中倒数第k个节点
- 二十九、合并两个排序的链表
- 三十、两个链表的第一个公共节点
- 三十一、调整数组顺序使奇数位于偶数前面
- 三十二、和为s的两个数字
- 三十三、翻转单词顺序
- 三十四、矩阵中的路径
- 三十五、机器人的运动范围
- 三十六、二叉树中和为某一值的路径
- 三十七、二叉搜索树与双向链表
- 三十八、二叉搜索树的第k大节点
- 三十九、把数组排成最小的数
- 四十、扑克牌中的顺子
- 四十一、最小的k个数
- 四十二、数据流中的中位数
- 四十三、二叉树的深度
- 四十四、平衡二叉树
- 四十五、求1+2+…+n
- 四十六、二叉搜索树的最近公共祖先
- 四十七、二叉树的最近公共祖先
- 四十八、重建二叉树
- 四十九、数值的整数次方
- 五十、二叉搜索树的后序遍历序列
- 五十一、二进制中1的个数
- 五十二、不用加减乘除做加法
- 五十三、数组中数字出现的次数
- 五十四、数组中数字出现的次数 II
- 五十五、数组中出现次数超过一半的数字
- 五十六、构建乘积数组
- 五十七、剪绳子
- 五十八、和为s的连续正数序列
- 五十九、圆圈中最后剩下的数字
- 六十、顺时针打印矩阵
- 六十一、栈的压入、弹出序列
- 六十二、表示数值的字符串
- 六十三、把字符串转换成整数
- 六十四、滑动窗口的最大值
- 六十五、队列的最大值
- 六十六、序列化二叉树
- 六十七、字符串的排列
- 六十八、正则表达式匹配
- 六十九、丑数
- 七十、n个骰子的点数
- 七十一、打印从1到最大的n位数
- 七十二、数组中的逆序对
- 七十三、剪绳子 II
- 七十四、1~n 整数中 1 出现的次数
- 七十五、数字序列中某一位的数字
一、用两个栈实现队列
题目
解题思路
维护两个栈,一个维护插入,一个维护删除。需要删除的时候可以把插入栈里的元素全部倒进删除栈里,注意只有删除栈为空了,才会倒,否则会破坏元素的顺序。很巧妙。
AC代码
class CQueue
stack<int> st1, st2;
public:
CQueue()
while (st1.size())
st1.pop();
while (st2.size())
st2.pop();
void appendTail(int value)
st1.push(value);
int deleteHead()
if (!st2.size()) //为空才会倒,才能保证顺序正确
while (st1.size())
st2.push(st1.top());
st1.pop();
if (!st2.size())
return -1;
int res = st2.top();
st2.pop();
return res;
;
二、包含min函数的栈
题目
为栈新增功能, O ( 1 ) O(1) O(1)得到栈中最小值。
解题思路
如果当前压入的元素不是最小值,那么它一定不会作为最小值。所以我们只需要开一个辅助单调栈维护好每个“在压入时是最小值”的元素。
AC代码
class MinStack
public:
stack<int> st, st2;
MinStack()
while (!st.empty())
st.pop();
while (!st2.empty())
st2.pop();
void push(int x)
st.push(x);
if (!st2.size() || x <= st2.top())
st2.push(x);
void pop()
if (st2.size() && st.top() == st2.top())
st2.pop();
st.pop();
int top()
return st.top();
int min()
return st2.top();
;
三、从尾到头打印链表
题目
解题思路
简单题,可以遍历一遍reverse,或者递归回溯打印。
AC代码
class Solution
public:
vector<int> reversePrint(ListNode *head)
vector<int> ans;
if (head == nullptr)
return ans;
if (head->next != NULL)
ans = reversePrint(head->next);
ans.emplace_back(head->val);
else
ans.emplace_back(head->val);
return ans;
;
四、反转链表
题目
解题思路
遍历并反转即可。
AC代码
class Solution
public:
ListNode *reverseList(ListNode *head)
vector<ListNode *> vec;
ListNode *pre = nullptr;
while (head != nullptr)
vec.emplace_back(head);
head = head->next;
vec.back()->next = pre;
pre = vec.back();
return pre;
;
五、复杂链表的复制
题目
解题思路
模拟一遍即可。
AC代码
class Solution
public:
const int N = 1e5 + 5;
Node *copyRandomList(Node *head)
vector<Node *> vec;
for (int i = 0; i < N; i++)
Node *ptr = new Node(1);
vec.emplace_back(ptr);
int id = 1, cnt = 1;
map<Node *, int> mp;
map<int, int> to;
Node *tmp = head;
vec[0] = nullptr;
while (head != nullptr)
mp[head] = cnt++;
head = head->next;
vec[cnt] = nullptr;
head = tmp;
while (head != nullptr)
vec[id]->next = vec[id + 1]; //指向后一个元素
vec[id]->val = head->val; //赋值
// to[i]=j表示i号结点random指向j号结点
to[id++] = mp[head->random];
head = head->next;
id = 1;
while (vec[id] != nullptr)
vec[id]->random = vec[to[id]];
id++;
return vec[1];
;
六、替换空格
题目
解题思路
无
AC代码
class Solution
public:
string replaceSpace(string s)
string ans;
for (auto it : s)
if (it == ' ')
ans += "%20";
else
ans += it;
return ans;
;
七、左旋转字符串
题目
解题思路
无
AC代码
class Solution
public:
string reverseLeftWords(string s, int n)
return s.substr(n) + s.substr(0, n);
;
八、数组中重复的数字
题目
解题思路
无
AC代码
class Solution
public:
int findRepeatNumber(vector<int> &nums)
set<int> st;
for (auto it : nums)
if (st.count(it))
return it;
st.insert(it);
return -1;
;
九、I. 在排序数组中查找数字
题目
解题思路
无
AC代码
class Solution
public:
int search(vector<int> &nums, int target)
map<int, int> mp;
for (auto it : nums)
mp[it]++;
return mp[target];
;
十、II. 0~n-1中缺失的数字
题目
解题思路
无
AC代码
class Solution
public:
int missingNumber(vector<int> &nums)
int ans = 0;
while (ans < nums.size() && nums[ans] == ans)
ans++;
return ans;
;
十一、二维数组中的查找
题目
解题思路
遍历每一列,采用二分,时间复杂度
O
(
n
l
o
g
m
)
O(nlogm)
O(nlogm)
官方题解:从右上角出发,边走边选择,时间复杂度
O
(
n
l
o
g
m
)
O(nlogm)
O(nlogm)
AC代码
class Solution
public:
bool findNumberIn2DArray(vector<vector<int>> &matrix, int target)
if (!matrix.size())
return 0;
int n = matrix.size();
int m = matrix[0].size();
for (int i = 0; i < n; i++)
int p = lower_bound(matrix[i].begin(), matrix[i].end(), target) - matrix[i].begin();
if (p != m && matrix[i][p] == target)
return 1;
return 0;
;
十二、旋转数组的最小数字
题目
解题思路
判断一下转折位置和corner test
即可。
AC代码
class Solution
public:
int minArray(vector<int> &numbers)
int n = numbers.size();
if (n == 1)
return numbers[0];
for (int i = 0; i < n - 1; i++)
if (numbers[i] > numbers[i + 1])
return numbers[i + 1];
return numbers[0];
;
十三、第一个只出现一次的字符
题目
解题思路
无
AC代码
class Solution
public:
char firstUniqChar(string s)
map<char, int> mp;
for (auto it : s)
mp[it]++;
for (auto it : s)
if (mp[it] == 1)
return it;
return ' ';
;
十四、I. 从上到下打印二叉树
题目
解题思路
遍历一遍即可。、
好吧,其实可以直接BFS。
AC代码
cla以上是关于leetcode剑指offer合集+题解的主要内容,如果未能解决你的问题,请参考以下文章