剑指Offer
fkuner
这个作者很懒,什么都没留下…
展开
-
剑指Offer系列39—数组中出现次数超过一半的数字
题意数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。题解常见的有三种解法哈希表统计法:用map来统计各数字的数量,即可找出众数数组排序法:将数组排序,数组中点元素一定为众数摩尔投票法:核心理念为票数正负相抵,此方法时间复杂度和空间复杂度分别为O(n)O(n)O(n)和O(1)O(1)O(1)摩尔投票法...原创 2020-12-01 09:28:14 · 64 阅读 · 0 评论 -
剑指Offer系列29—顺时针打印矩阵
题意输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。题解方法一:模拟class Solution {private: static constexpr int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};public: vector<int> spiralOrder(vector<vector<int>>& matrix) { if (matr原创 2020-11-30 10:25:48 · 163 阅读 · 0 评论 -
剑指Offer系列40—最小的K个数
题意输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。题解方法一:排序class Solution {public: vector<int> getLeastNumbers(vector<int>& arr, int k) { vector<int> vec(k, 0); sort(arr.begin(), arr.end());原创 2020-11-27 15:13:27 · 116 阅读 · 0 评论 -
剑指Offer系列35—复杂链表的复制
题意请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null题解实现链表的深拷贝,方法很多,这里写一个最技巧的解法:拼接+拆分class Solution {public: Node* copyRandomList(Node* head) { if(head == nullptr) return nullptr; Node* c原创 2020-11-27 09:26:37 · 59 阅读 · 0 评论 -
剑指Offer34—二叉树中和为某一值的路径
题意输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。题解/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {原创 2020-11-26 22:03:47 · 74 阅读 · 0 评论 -
剑指Offer系列33—二叉搜索树的后续遍历序列
题意输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回true,否则返回 false。假设输入的数组的任意两个数字都互不相同。题解class Solution {public: bool verifyPostorder(vector<int>& postorder) { return recur(postorder, 0, postorder.size()-1); } bool recur(vector<int原创 2020-11-26 21:52:17 · 73 阅读 · 0 评论 -
剑指Offer系列32—从上到下之字形打印二叉树
题意请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。题解/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), rig原创 2020-11-26 21:30:24 · 126 阅读 · 1 评论 -
剑指Offer系列31—栈的压入、弹出序列
题意输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。题解class Solution {public: bool validateStackSequences(vector<int>& pushed, vector<int>原创 2020-11-25 18:41:04 · 152 阅读 · 0 评论 -
剑指Offer系列30—包含min函数的栈
题意定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)O(1)O(1)。题解//Javaclass MinStack { Stack<Integer> A, B; public MinStack() { A = new Stack<>(); B = new Stack<>(); } public void原创 2020-11-25 18:23:01 · 70 阅读 · 0 评论 -
剑指Offer系列28—对称的二叉树
题意请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。题解class Solution { public boolean isSymmetric(TreeNode root) { return root == null ? true : recur(root.left, root.right); } boolean recur(TreeNode L, TreeNode R) { if(L == null原创 2020-11-21 20:38:29 · 67 阅读 · 0 评论 -
剑指Offer系列27—二叉树的镜像
题意请完成一个函数,输入一个二叉树,该函数输出它的镜像。题解/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:原创 2020-11-21 19:22:39 · 56 阅读 · 0 评论 -
剑指Offer系列26—树的子结构
题意输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)B是A的子结构, 即 A中有出现和B相同的结构和节点值。题解/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NUL原创 2020-11-21 19:13:52 · 129 阅读 · 0 评论 -
剑指Offer25—合并两个排序的列表
题意输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。题解双指针+递归其实不用递归也行,但是创建一个新链表,不是一个极客的行为/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {原创 2020-11-21 18:22:16 · 60 阅读 · 0 评论 -
剑指Offer系列22—链表中倒数第k个节点
题意输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。题解同剑指Offer系列21—调整数组顺序使奇数位于偶数前面,双指针轻松解决/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode原创 2020-11-21 18:13:38 · 77 阅读 · 0 评论 -
剑指Offer系列21—调整数组顺序使奇数位于偶数前面
题意输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。题解双指针轻松解决,注意判断条件class Solution {public: vector<int> exchange(vector<int>& nums) { // 双指针,i表示 int i = 0; int j = nums.size() - 1; while(i &l原创 2020-11-21 18:09:26 · 58 阅读 · 0 评论 -
剑指Offer系列24—反转链表
题意定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。题解方法一:迭代+双指针/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode* reve原创 2020-11-18 15:05:48 · 218 阅读 · 0 评论 -
剑指Offer系列17—打印从1到最大的n位数
题意输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。题解实际考察大数越界的情况,应该用字符串来存https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/solution/mian-shi-ti-17-da-yin-cong-1-dao-zui-da-de-n-wei-2/...原创 2020-11-05 17:21:55 · 47 阅读 · 0 评论 -
剑指Offer系列15—二进制中1的个数
题意请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。题解逐位判断即可class Solution {public: int hammingWeight(uint32_t n) { int res = 0; while(n != 0){ res += n & 1; n >>= 1;原创 2020-11-05 16:59:21 · 51 阅读 · 0 评论 -
剑指Offer系列13—机器人的运动范围
题意地上有一个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。请问该机器人能够到达多少个格子?题解广度优先遍历//C++class Solution {public: int原创 2020-11-05 16:46:57 · 96 阅读 · 0 评论 -
剑指Offer系列18—删除链表的节点
题意给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。题解//C++/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNod原创 2020-11-05 10:39:07 · 53 阅读 · 0 评论 -
剑指Offer系列12—矩阵中的路径
题意请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。[[“a”,“b”,“c”,“e”],[“s”,“f”,“c”,“s”],[“a”,“d”,“e”,“e”]]但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第原创 2020-11-03 08:21:33 · 135 阅读 · 0 评论 -
剑指Offer系列11—旋转数组的最小数字
题意把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。问题分析class Solution {public: int minArray(vector<int>& numbers) { int low = 0; int high = numbers.size() - 1;原创 2020-10-31 10:01:15 · 63 阅读 · 0 评论 -
剑指Offer系列10-2—青蛙跳台阶问题
题意一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。问题分析与斐波那契数列类似class Solution {public: int numWays(int n) { int a = 1, b = 1, sum; for(int i = 0; i < n; i++) {原创 2020-10-30 20:57:22 · 60 阅读 · 0 评论 -
剑指Offer系列10-1—斐波那契数列
题意写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:F(0) = 0, F(1) = 1F(N) = F(N - 1) + F(N - 2), 其中 N > 1.斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。问题分析递归会进行大量重复的计算,涉及大量重复计算的问题可以用动态规划来解决设dp[i]的原创 2020-10-30 20:45:26 · 148 阅读 · 0 评论 -
剑指Offer系列9—用两个栈实现队列
题意用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )问题分析class CQueue { LinkedList<Integer> A, B; public CQueue() { A = new LinkedList<Integer>(); B = new Li原创 2020-10-30 20:23:28 · 61 阅读 · 0 评论 -
剑指Offer系列7—重建二叉树
题意输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。问题分析递归不解释/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */class Solut原创 2020-10-30 17:53:09 · 58 阅读 · 0 评论 -
剑指Offer系列6—从尾到头打印链表
题意输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。问题分析方法一:递归class Solution { ArrayList<Integer> tmp = new ArrayList<Integer>(); public int[] reversePrint(ListNode head) { recur(head); int[] res = new int[tmp.size()]; for(i原创 2020-10-30 16:12:35 · 92 阅读 · 0 评论 -
剑指Offer系列5—替换空格
题意请实现一个函数,把字符串 s 中的每个空格替换成"%20"。示例 1:输入:s = “We are happy.”输出:“We%20are%20happy.”限制:0 <= s 的长度 <= 10000问题分析方法一:字符数组class Solution { public String replaceSpace(String s) { int length = s.length(); char[] array = new ch原创 2020-10-30 16:06:55 · 201 阅读 · 0 评论 -
剑指Offer系列3—数组中重复的数字
题意找出数组中重复的数字。在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。示例 1:输入:[2, 3, 1, 0, 2, 5, 3]输出:2 或 3限制:2 <= n <= 100000问题分析方法一:排序class Solution {public: int findRepeatNumber(vector<int原创 2020-10-30 15:46:29 · 106 阅读 · 0 评论 -
剑指Offer系列68-2—二叉树的最近公共祖先
题意给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。问题分析class Solution: def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode: if not root or root == p or root == q: return root left = self.lowestCommonAncestor(root.left,原创 2020-10-30 11:28:43 · 56 阅读 · 0 评论 -
剑指Offer系列68-1—二叉搜索树的最近公共祖先
题意给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。问题分析class Solution {public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { // if(root == NULL) return NULL; if(root->val > p->val && root->val > q-&g原创 2020-10-30 10:38:29 · 51 阅读 · 0 评论 -
剑指Offer系列67—把字符串转换成整数
题意写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。注意:假如该字符串中的第一原创 2020-10-30 10:14:40 · 57 阅读 · 0 评论 -
剑指Offer系列66—构建乘积数组
题意给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。示例:输入: [1,2,3,4,5]输出: [120,60,40,30,24]提示:所有元素乘积之和不会溢出 32 位整数a.length <= 100000问题分析构造一个乘积矩阵,详情见《剑指Offer》class Solution { public int[] c原创 2020-10-29 17:36:19 · 57 阅读 · 0 评论 -
剑指Offer系列65—不用加减乘除做加法
题意写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。问题分析由于不能使用四则运算,只能考虑使用位元算class Solution {public: int add(int a, int b) { int sum; int carry; do{ sum = a ^ b; carry =(unsigned int)(a & b) <&l原创 2020-10-29 17:05:56 · 51 阅读 · 0 评论 -
剑指Offer系列62—圆圈中最后剩下的数字
题意0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。示例 1:输入: n = 5, m = 3输出: 3限制:1 <= n <= 10^51 <= m <= 10^6问题分析方法一:环形链表模拟圆圈(超时)class Solution {p原创 2020-10-29 16:13:24 · 44 阅读 · 0 评论 -
剑指Offer系列63—股票的最大利润
题意假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?示例 1:输入: [7,1,5,3,6,4]输出: 5解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。限制:0 <= 数组长度 <= 10^5问题分析蛮力法的时间复杂度为O(n2)O(n^2)O(n2)应该用动态规划的思想来解决,原创 2020-10-29 15:04:46 · 69 阅读 · 0 评论 -
剑指Offer系列61-扑克牌中的顺子
题意从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。问题分析根据题意,5张牌是顺子的充分条件是:除大小王外,所有牌 无重复;设此 5 张牌中最大的牌为 max,最小的牌为 min (大小王除外),则需满足:max - min < 5方法一:集合+遍历//Javaclass Solution { public boolean isStraig原创 2020-10-28 14:40:47 · 96 阅读 · 0 评论 -
剑指Offer系列60—n个骰子的点数
题意把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。问题分析动态规划class Solution {public: vector<double> twoSum(int n) { vector<double> res; int dp[12][6*n+1]; memset(dp,0,sizeof(dp)); for(int i = 1; i &原创 2020-10-28 11:56:59 · 58 阅读 · 0 评论 -
剑指Offer系列59-2—队列的最大值
题意请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。若队列为空,pop_front 和 max_value 需要返回 -1问题分析与上题滑动窗口的最大值类似,用单调队列即可解决,同时维护一个辅助队列即可。class MaxQueue { queue<int> q; deque<int> d;public: MaxQueue() {原创 2020-10-28 10:19:31 · 76 阅读 · 0 评论 -
剑指Offer系列59-1—滑动窗口的最大值
题意给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。问题分析单调队列//C++class Solution {public: vector<int> maxSlidingWindow(vector<int>& nums, int k) { vector<int> res; deque<int> dq; int len = nums.size();原创 2020-10-28 09:52:37 · 74 阅读 · 0 评论