剑指Offer
Data跳动
专注于数据开发,数仓建设,数据治理以及大数据生态技术
展开
-
【剑指 Offer 】45. 把数组排成最小的数
题目:45. 把数组排成最小的数思路:根据冒泡法进行组合比较两个字符串拼接在一起两种情况的大小,取结果最小的作为排序结果;例如,两个字符串s1,s2:两种拼接方式拼接起来,比较s1s2与s2s1哪个值小?如果s1s2值较小,则s1排在s2前面。题解class Solution { public String minNumber(int[] nums) { int len = nums.length; //特判 if(len == 0原创 2020-10-29 19:15:28 · 100 阅读 · 0 评论 -
【剑指 Offer】44. 数字序列中某一位的数字
题目: 44. 数字序列中某一位的数字思路:若想要求第n位:先求第n位所在的数字num的位数digit,比如第11位所在的数字num为10,位数为2;求所在的数字num;求所在num的第几位;题解class Solution { public int findNthDigit(int n) { //初始化 int digit = 1; //位数 int start = 1; //每个digit开始的数字 int原创 2020-10-29 10:21:34 · 167 阅读 · 0 评论 -
【剑指 Offer 】43. 1~n整数中1出现的次数
题目:1~n整数中1出现的次数思路:以cur所指向的位数的数字为界,将数字分为三个部分:左边高位组成的数为high,右边低位组成的数为low,cur指向数组的位数为digit;cur从低位依次遍历到高位,累加cur在每一个位置上包含1的个数;当cur所指的数字为0时,1出现的次数为: high * digit;当cur所指的数字为1时,1出现的次数为: high * digit + low + 1;当cur所指的数字为其他数字时,1出现的次数为: (high+1) * digit;代码:原创 2020-10-09 22:13:20 · 157 阅读 · 0 评论 -
【剑指 Offer 】42. 连续子数组的最大和
题目:42. 连续子数组的最大和分析:状态dp[i]: 表示从0到i的连续子数组的最大和;初始状态:dp[0] = nums[0];转移方程: dp[i] = Math.max(dp[i-1],0) + nums[i];最后求出的dp[]数组相当于一个状态表,每个位置代表着以这个位置结尾的最大连续子数组的最大和。所以,整个数组nums中连续子数组的最大和,就是dp[]数组中最大的值。解题思路:创建一个dp[]数组,一个记录最大和的变量res;赋初始值dp[0];遍历数组,更新dp原创 2020-10-07 16:57:04 · 109 阅读 · 0 评论 -
【剑指 Offer 】41. 数据流中的中位数
题目:41. 数据流中的中位数思路:写一个数据结构,实现数据流的动态添加和查找实时的中位数。(奇数个的时候中位数为A的堆顶元素)静态变量:小顶堆A、大顶堆B;存放数据:先判断A和B的大小:相等的话,就存在A中;不相等的话,就存在B中;读取中位数:判断A和B的大小:相等就取两者堆顶元素的平均值;不相等,就弹出A的堆顶元素;代码:class MedianFinder { // 静态变量 Queue<Integer> A,B; //原创 2020-10-07 16:11:17 · 196 阅读 · 0 评论 -
【剑指 Offer 】40. 最小的k个数
题目:40. 最小的k个数思路大顶堆:堆顶元素就是堆中所有元素中最大的那个元素。遍历数组:如果堆中元素不足K个,那么就是直接添加;当堆中元素大于等于K个时,就要将堆顶元素与遍历到的当前元素比较:比栈顶元素大就跳过;比栈顶元素小,那么栈就弹出栈顶元素,然后将该元素放入栈中;class Solution { public int[] getLeastNumbers(int[] arr, int k) { // 特判 if(k == 0 || k原创 2020-10-07 14:26:28 · 195 阅读 · 0 评论 -
【剑指 Offer 】39. 数组中出现次数超过一半的数字
题目:39. 数组中出现次数超过一半的数字思路初始化:众数mode:初始值设置为数组的第一个元素;票数vote:表示当前众数mode所获得的票数,初始值设置为0;遍历,对每个元素e进行如下操作:判断票数vote是否为0:为0则将当前遍历的元素e设置为众数mode;判断e是否为众数mode:是 ==> vote + 1;否 ==> vote - 1;返回最终选举的众数mode。代码:class Solution { public int ma原创 2020-10-06 18:04:58 · 99 阅读 · 0 评论 -
【剑指 Offer 】31. 栈的压入、弹出序列
题目:31. 栈的压入、弹出序列思路:借助一个栈stack,一个弹出序列的索引index特判:压栈序列和弹出序列长度不一致,肯定返回false;遍历压栈序列:将读取的元素添加到栈stack中;只要栈顶元素和弹出序列的元素相同,就弹出栈,然后索引index++;代码:class Solution { public boolean validateStackSequences(int[] pushed, int[] popped) { //特判 if原创 2020-10-06 17:30:48 · 88 阅读 · 0 评论 -
【剑指 Offer 】30. 包含min函数的栈
题目:30. 包含min函数的栈思路分析:成员变量:定义两个队列stackA和stackB构造方法:给两个队列创建对象push: 添加元素e的时候,stackA正常添加,stackB需要比较一下,如果e小于等于栈顶元素的话,就添加,否则,过!!pop: 弹出的时候stackA正常弹出栈顶元素e,如果stackB的栈顶元素和e相同,那么stackB也要弹出栈顶元素;top: 直接读取stackA的栈顶元素;min: 直接读取stackB的栈顶元素;class MinStack {原创 2020-10-05 17:34:48 · 109 阅读 · 0 评论 -
【剑指 Offer 】29. 顺时针打印矩阵
题目:29. 顺时针打印矩阵思路:根据题意,需要特判,对于空矩阵直接返回空数组。接下来:定义出二维数组的左右上下四个边界,left、right、top、bottom;循环打印:沿着top,从左向右打印,top++;沿着right,从上向下打印,right--;沿着bottom,从右向左打印,bottom++;沿着left,从下向上打印,left++;注:在沿着下边界和左边界打印时,要确保left <= right,top <= bottom。代码:class原创 2020-10-05 17:24:45 · 92 阅读 · 0 评论 -
【剑指 Offer 】21. 调整数组顺序使奇数位于偶数前面
题目:21. 调整数组顺序使奇数位于偶数前面这道题和283.移动零 非常类似。思路特判: 过滤掉空数组;定义一个指针p表示已经遇到的奇数元素的个数,初始值为0;遍历:遇到奇数的元素就放在p的位置上,然后p++;class Solution { public int[] exchange(int[] nums) { int p = 0; int len = nums.length; for(int i = 0; i < l原创 2020-10-05 09:20:11 · 91 阅读 · 0 评论 -
【剑指 Offer 】17. 打印从1到最大的n位数
题目:17. 打印从1到最大的n位数思路:输入n,就要打印从1到n个9组成的数字;计算出n个9代表的数字num;遍历打印1到num;class Solution { public int[] printNumbers(int n) { //生成n String str = ""; for(int i = 0; i < n; i++){ str += 9; } long end原创 2020-10-05 09:12:29 · 148 阅读 · 0 评论 -
【剑指 Offer 】16. 数值的整数次方
题目: 16. 数值的整数次方思路:如果n为负数,那么x取倒数,保证n为正数;先判断n是否为奇数是奇数,由于接下来还要减半,需要将多余的x累乘积到res中;n除以2减半;x自身相乘;这里需要注意的是:n为int型,取值范围为[-2^31, 2^31-1];如果n为负数,x取倒数,n取相反数变成正数,恰如恰好x为-2^31,而其相反数2^31不在int型范围内,所以要将n转化为long型;代码class Solution { public double myPow原创 2020-10-04 21:33:59 · 91 阅读 · 0 评论 -
【剑指 Offer 】15. 二进制中1的个数
题目:15. 二进制中1的个数思路1:本题可以判断n的最后一位是否为1,来计算1的个数,采用逻辑右移的方式。(对算术右移和逻辑右移分不清的可以看这篇文章)。代码:public class Solution { // you need to treat n as an unsigned value public int hammingWeight(int n) { int sum = 0; while(n!=0){ sum +原创 2020-10-04 20:28:07 · 95 阅读 · 0 评论 -
【剑指 Offer 】14- II. 剪绳子 II
题目:14- II. 剪绳子 II参考14-I.剪绳子I在此基础上,每累积3之后,要取模。分析:当绳子长度大于4时,尽可能多的分成长度为3的小段,这样乘积是最大的。(数学证明自行查找)思路:n小于4时,返回n-1;n等于4时,返回4;n大于4时,就要切割成长度为3的小段,只要n还大于4,每切除一段3,就累乘起来,然后取模。代码:class Solution { public int cuttingRope(int n) { if(n < 4){原创 2020-10-04 20:05:07 · 116 阅读 · 0 评论 -
【剑指 Offer】14- I. 剪绳子
题目:14- I. 剪绳子分析:当绳子长度大于4时,尽可能多的分成长度为3的小段,这样乘积是最大的。(数学证明自行查找)思路:n小于4时,返回n-1;n等于4时,返回4;n大于4时,就要切割成长度为3的小段,只要n还大于4,每切除一段3,就累乘起来。代码:class Solution { public int cuttingRope(int n) { if(n < 4){ return n - 1; }else if原创 2020-10-04 19:54:23 · 114 阅读 · 0 评论 -
【剑指 Offer】13. 机器人的运动范围
题目:13. 机器人的运动范围思路:借助一个辅助方法helper来判别二维方格的每个位置是否满足条件,如果满足则计数+1;helper方法实现:先判断位置是否越界,是否遍历过,数位和是否满足条件,不满足则返回;计数+1,递归遍历下一个位置;将该位置标记已经访问过;class Solution { //成员变量 int m , n , k , res; boolean[][] visited; public int movingCount(int m,原创 2020-10-04 19:23:52 · 104 阅读 · 0 评论 -
【剑指 Offer 】12. 矩阵中的路径
题目:12. 矩阵中的路径分析借助一个辅助方法helper,传入的参数为board,word以及分别记录其元素位置的指针i、j,p;判断i,j是否越界,字符是否匹配;以上没问题了,再看看是不是最后一个word字符了;将当前遍历的board元素暂时存放起来,其位置做个标记,表示已经访问过了;从该位置分别对四个方向递归搜索;递归完之后再将该位置的元素还原;思路:遍历board中的元素,对每一个位置调用helper方法,只要有一处返回true,就结束。代码:class Solution原创 2020-10-04 10:33:28 · 83 阅读 · 0 评论 -
【剑指 Offer】11. 旋转数组的最小数字
题目:11. 旋转数组的最小数字思路初始化两个指针left,right分别指向数组首尾;开始二分搜索,求mid,然后和right位置的数字进行比较;若 nums[mid] 大于 nums[right],则说明最小值在mid右侧,那么左边界left = mid + 1;若 nums[mid] 小于 nums[right],则说明最小值在mid左侧,那么右边界right = mid;若 nums[mid] 等于 nums[right],那么右边界左移,right --;class S原创 2020-10-03 21:57:27 · 2306 阅读 · 0 评论 -
【剑指 Offer 】10- II. 青蛙跳台阶问题
题目:10- II. 青蛙跳台阶问题思路分析:本质是在求斐波那契数列,也就是当前值是前两个值之和。初始化cur代表当前i台阶的走法,初始值为1;pre代表i-1台阶的走法,初始值为1;迭代,每求增加一个台阶,就要进行如下操作:更新cur = cur + pre;更新pre = cur - pre;返回curclass Solution { public int numWays(int n) { //初始化 int pre =原创 2020-10-03 18:41:46 · 74 阅读 · 0 评论 -
【剑指 Offer】10- I. 斐波那契数列
题目:10- I. 斐波那契数列思路:采用双指针法初始化:pre = 0;cur = 1;每次迭代更新:cur = cur + pre;pre = cur - pre;在本题中,要求返回结果取模,那么在计算cur时就需要进行取模。class Solution { public int fib(int n) { // 特判 if(n == 0) return 0; // 初始化 int pre = 0原创 2020-10-03 18:27:27 · 106 阅读 · 0 评论 -
【剑指 Offer】09. 用两个栈实现队列
题目:09. 用两个栈实现队列思路:用栈A和栈B来实现队列,其中栈A负责插入数据,栈B负责删除数据。为了实现队列先进先出的特点,在栈B为空时,需要将栈A中的数据取出插入栈B中。代码:class CQueue { //成员变量 Stack<Integer> A,B; //构造方法 public CQueue() { A = new Stack<>(); B = new Stack<>原创 2020-10-03 18:08:27 · 102 阅读 · 0 评论 -
【剑指 Offer】04. 二维数组中的查找
题目:04. 二维数组中的查找分析:根据二维数组的特点,我们发现如果将最后一行或者最后一列的元素与target作比较,可以筛选至少一行或一列的元素,非常高效。思路:从右上角开始遍历最后一列,也可从左下角遍历最后一行;将元素与target相比较:若相同:则证明包含,返回true;若小于:则证明此行元素均小于target,继续下一行,即i++;若大于:则说明此行元素有可能包含,开始遍历此行,即j--;(由于剩下的几行元素均大于target,自然不用继续再遍历判断了)代码:clas原创 2020-10-03 17:40:43 · 162 阅读 · 0 评论 -
【剑指 Offer】 03. 数组中重复的数字
题目 03. 数组中重复的数字方法一:哈希遍历一次过!思路:申请一个hashset,然后遍历数组,对数组中的每一个元素作如下操作:检查hashset中是否包含该元素;如果包含,说明该元素是重复的,直接返回;若不包含,则将该元素添加到集合中;代码class Solution { public int findRepeatNumber(int[] nums) { HashSet<Integer> hashset = new HashSet<&原创 2020-10-03 17:06:22 · 108 阅读 · 0 评论