剑指offer
_龙卷风_
这个作者很懒,什么都没留下…
展开
-
leetcode刷题记录
对应剑指offer刷题记录,leetcode也来个。 1.27. 移除元素原创 2020-11-14 23:51:45 · 155 阅读 · 1 评论 -
3rd刷剑指offer,问题汇总
1.剑指 Offer 14- II. 剪绳子 II,这道题目关于求余算法,还没有掌握。原创 2020-11-09 18:14:01 · 282 阅读 · 0 评论 -
剑指 Offer 11. 旋转数组的最小数字
类似于已经排序的数组,一般都是用二分法来求解,定义两个首尾指针,当两个指针重合时,则返回,主要是找到arr[mid]与arr[i]和arr[j]大小判断后,指针的移动情况。 题目中的数组是由一个升序数组反转来的,因此可将数组分为两部分,左半部分为较大部分数组,右半部分为较小升序数组,我们要找的就是右部分数组的第一个元素。 首先定义首位指针i,j,在i < j的时候进行指针移动,当arr[i] < arr[j]时,通过题目给的示例数组,可以发现此时目标元素在i和mid指针中间,因此让j =..原创 2020-10-02 09:38:51 · 108 阅读 · 0 评论 -
剑指 Offer 10- II. 青蛙跳台阶问题
这道题是斐波那契数列的变种,也可以说是动态规划,都是从下往上挨个计算,直到我们需要的那个数值。第n个台阶的所有跳法,等于第n-1个台阶的跳法+第n-2个台阶的跳法。原因如下: 代码: class Solution { public int numWays(int n) { if (n < 0) return -1; int f0 = 1, f1 = 1, ans = 0; if (n < 2) return 1; ...原创 2020-09-30 15:43:54 · 163 阅读 · 0 评论 -
剑指 Offer 14- II. 剪绳子 II
这道题与I类似,但是数据量更大,且需要求模,用我之前的代码我时没有AC。借此也在这里给出一种数学推导,知道要怎么划分之后,面向答案编程。原创 2020-09-30 12:26:15 · 104 阅读 · 0 评论 -
剑指 Offer 14- I. 剪绳子
这道题乍一看感觉彷佛没思路,例如要切多少段绳子,每段绳子的长度是多少才能让绳子段数乘积最大,似乎组合性太多了,根本找不出来。但是可以换一个角度(动态规划),定义一个函数y=f(n),表示绳子长度为n时,满足题目要求的最大值。比如f(12),就表示绳子长度为12时,题目要求的最大值就是这个。 动态规划一般都会用到数组来记录每一个f(n)的值,并且计算过程是从下向上的,我们一般可以从题目或手动计算一些初始信息,比如f(0),f(1), f(2)等等,然后根据f(n)和f(n-1),f(n-2)来计算出f(..原创 2020-09-30 10:38:08 · 92 阅读 · 0 评论 -
剑指 Offer 10- I. 斐波那契数列
很明显可以根据斐波那契额数列的定义f(n) = f(n-1) + f(n-2),可以给定初始条件,利用递归来做。但是像这种情况,递归的话先不说内存的问题,每一次计算时,因为是从上向下计算的,所以会有大量的重复数据,并且这个重复数据的出现对f(n)并没用帮助。这种情况一般采用从下向上开始计算,并且不是递归的形式,而是采用辅助变流 ...原创 2020-09-30 10:09:30 · 143 阅读 · 0 评论 -
剑指 Offer 09. 用两个栈实现队列
队列的特点是先进先出,而栈的特点是先进后出,但是这道题我们可以利用两个栈来实现队列的特点。 定义了两个栈,queue作为主要的栈,aux为辅助队列。初始时刻优先将数值放入到queue中,当queue中有一个数值时,就将余下的数值放入到aux中。队列首个数值出队时,这是queue中是空,然后需要将aux中的数值弹出并压入到queue中,这时的顺序已经翻转过来了,再下次出队时,直接pop即可。当queue为空时,执行前述步骤。 代码如下: class CQueue { Stack<In..原创 2020-09-25 22:19:54 · 98 阅读 · 0 评论 -
剑指 Offer 07. 重建二叉树
首先要懂得前序遍历和中序遍历,可以写出两个数组,自己手动来重建一下二叉树,来看看重建二叉树是怎么一个流程。 以图中给出的二叉树为例, 根据前序遍历的特点,可知前序遍历的首尾数字是根节点,比如这个时候根节点数值为3,可以在中序遍历中第2个位置找到数值3,在3左边的9为3的左子树,右边的15,20,7为右子树。同时可以把前序数组划分为两个数组,即左子树的前序遍历数组9,右子树的前序遍历数组20,15,7,采用递归的方式进行求解。 我自己的写法中,是以中序遍历为依据返回节点的。当中序遍历数组的左边指...原创 2020-09-25 21:43:02 · 104 阅读 · 0 评论 -
剑指 Offer 06. 从尾到头打印链表
链表定义: /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ 1.递归: 如果题做的多了,一下就能想出用递归的方式去做,递归还是自己多做题多领会吧,实在想不过来去算一遍数学中的均差。 代码如下: class Solution { ...原创 2020-09-24 20:09:05 · 94 阅读 · 0 评论 -
剑指 Offer 05. 替换空格
像有的题目,不要陷入一个圈套,无法换个角度来求解问题。比如这道题,要求去替换空格,初次做的话可能会想着怎么在原字符串上找到空格,然后把空格替换。其实可以换个角度,我们重新来构建一个字符串。 简单题,可以用一个StringBuilder实现动态从0构建题目要求的字符串。遍历原来那个字符串,如果遇到空格则添加%20,否则直接添加当前遍历到的char。 代码如下: class Solution { public String replaceSpace(String s) { ...原创 2020-09-24 19:48:36 · 103 阅读 · 0 评论 -
剑指 Offer 04. 二维数组中的查找
这道题也是需要抓住给的条件,两个递增。我们可以利用右上角或者左下角两个点作为起点,因为这两个点向两个方向有不同的的大小变化,可以更快的剔除不符合条件的行或者列。 代码如下: class Solution { public boolean findNumberIn2DArray(int[][] matrix, int target) { //一定不要忘记代码的鲁棒性 if (matrix == null || matrix.length == 0 || ...原创 2020-09-24 19:36:50 · 94 阅读 · 0 评论 -
剑指 Offer 03. 数组中重复的数字
题目如图片所示。像这种比较简单的题目,除了采用一些比较“暴力”的解法,求解的关键一般在于问题给出的特殊条件,本题中数组nums的长度为n,其中所有的数字都在0~n-1范围内就是解题关键点 1.比较笨拙的办法: 直接将数组排序,例如按升序排列,此时重复的数字一定是挨着的,因此可以用一个循环来判断是否有重复。 代码如下: class Solution { public int findRepeatNumber(int[] nums) { Arrays.sort(nums);..原创 2020-09-24 19:26:30 · 113 阅读 · 0 评论 -
剑指 Offer 13. 机器人的运动范围
这道题也需要采用回溯法来解决,同时又可分为深度优先dfs和广度优先bfs实现。 深度优先代码如下: class Solution { int row, column; boolean[][] isVisited; public int movingCount(int m, int n, int k) { row = m; column = n; isVisited = new boolean[m][n]; ...原创 2020-09-16 09:03:17 · 169 阅读 · 1 评论 -
剑指 Offer 12. 矩阵中的路径
题目如图片所示。这种题需要用到回溯法(等会开个算法专栏,系统学习一下),主要是要设定好减枝条件和返回条件。 这道题采用了深度优先方法,代码如下: class Solution { public boolean exist(char[][] board, String word) { if (board == null || word.length() < 1 || word == null) return false; char[] target = ..原创 2020-09-16 08:51:58 · 110 阅读 · 0 评论 -
剑指 Offer 32 - III. 从上到下打印二叉树 III (左右顺序交替,一层一层打印)
此题目又增加了一个要求,每一层地打印顺序变换着来。对此我的想法是,加入一个判断地flag,通过if(flag)来实现顺序地改变,同时每一层的临时数据结构由前面两道题的ArrayList变为LinkedList,实现两端都能添加数据。改变主要体现在,每一层的list,添加节点的位置,前面两道都是直接使用list.add()将数值添加到最后,改变时可以用list.adFirst()方法,就能实现顺序的翻转;或者可以使用工具类Colletcions.reverse()方法,添加完毕后直接翻转整个链表。 我...原创 2020-09-11 12:23:03 · 135 阅读 · 0 评论 -
剑指 Offer 32 - II. 从上到下打印二叉树 II (要求一层一层地输出)
这道题目增加了一个要求,即一层一层的打印节点,因此重点在于如何分层。 可以记录下队列未加入新节点时的数组长度,即本层的节点个数,然后用循环的方式将这一层的节点输出。 我的代码如下: class Solution { public List<List<Integer>> levelOrder(TreeNode root) { if (root == null) return new ArrayList<>(); Linke..原创 2020-09-11 11:53:45 · 93 阅读 · 0 评论 -
剑指 Offer 32 - I. 从上到下打印二叉树
很明显这里不能用解决树问题最常用的前序,中序,后续算法。结合队列先进先出的特点,可以利用队列来完成此题。 我的代码: class Solution { public int[] levelOrder(TreeNode root) { if (root == null) return new int[0]; LinkedList<TreeNode> list = new LinkedList<>(); ArrayList..原创 2020-09-11 11:39:59 · 67 阅读 · 0 评论 -
剑指 Offer 67. 把字符串转换成整数
题目及例子如上。 本题核心的问题,就是根据字符串str来生成int型数值。比较简便的是从字符串的左边向右边生成: for (int i = 0; i < str.length(); i++) { ans = ans * 10 + str.charAt(i) - '0'; //将对应的'x'转换为实际的x数值 } 这个核心问题解决之后,关键就是要得到符合我们要求的str,即str全为数字 1.用flag去应对str首字母为+或者-的情况 2.可以用St...原创 2020-08-19 00:16:12 · 187 阅读 · 0 评论 -
剑指 Offer 66. 构建乘积数组
题目如上。思路如下: 我们假设应该返回的答案为数组ans。显而易见B的数组长度应等于入参a数组的长度。 按照题意,对应于ans数组中的每一个元素ans[i],其大小应为: <math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mi>a</mi><mi>n</mi><mi>s</mi><mo stretchy="false">...原创 2020-08-16 21:18:02 · 103 阅读 · 0 评论 -
剑指 Offer 61. 扑克牌中的顺子
题目如图片所示。这道题目,其实一看到数组就能判断是不是能成为顺子,关键是要把人的思维转换成计算机的语言。此题主要用到了三个逻辑来判断。 利用Arrays.sort()将数组排序,便于循环判断。 判断数组中是否有对子出现,若有对子(两个数一样),则肯定不能成为顺子。代码表现为,判断数组中前后两个数大小是相等。 计算出数组中0的个数,因为0可以当作任意数组使用。 计算出数组中不是连续数字的个数,并且得出数字间隔的总数。例如,3,4 这两个数是连续数字,则间隔是0,如果是3,6那么间隔就是6-3-1=..原创 2020-07-24 22:21:35 · 158 阅读 · 0 评论 -
剑指 Offer 58 - I. 翻转单词顺序
题目: leetcode上面这道题与书上有些许不同,leetcode还考虑句子首尾和末尾有空格的情况,以及单词之间存在多个空格。 思路1: 这道题目的核心就是将单词顺序反转,不是一味地从头到尾将所有英文字母反转。因此可以借助于两个辅助指针,从尾到头进行扫描单词,利用StrinBuilder的append函数倒序地添加字符串中的单词。String的trim函数用于剔除字符串首尾的空格。 代码: class Solution { public String reverseWords(S.原创 2020-06-28 08:17:14 · 174 阅读 · 0 评论 -
剑指 Offer 57 - II. 和为s的连续正数序列
先上图: 给一下写的比较好的题解:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/solution/shi-yao-shi-hua-dong-chuang-kou-yi-ji-ru-he-yong-h/ 我的理解:我们利用一个数组来充当一个滑动窗口,左闭右开。用low指针来指向窗口的左端,用high来指向窗口的右端,注意high指针是开区间。用res来记录滑动窗口当前所有的和,为此可以简化计算,.原创 2020-06-24 23:34:59 · 152 阅读 · 0 评论 -
剑指offer 57:和为s的两个数字
先放图: 先说传统的暴力解法,就是用双重循环,先固定一个数,然后从它后面的数字去找。时间复杂度为O(n^2),面试时肯定不行的。不过剑指说面试时有思路可以立即说出来,反映你思维敏捷。。 放下暴力解法代码: class Solution { public int[] twoSum(int[] nums, int target) { if (nums == null) return null; int l = 0, h = 0; for (in原创 2020-06-20 20:25:34 · 116 阅读 · 0 评论 -
剑指Offer56:数组中除了一个数A,其他的数均出现三次,找出数A
觉得做过的题也必须写写博客,不然当时两三天能够记住,过段时间就只能记住思想,代码完全敲出来就有点僵硬了。。。还是踏实点 先把题目贴出来: 这道题书上应该要求是空间复杂度为O(1),否则这题用HashMap就能轻松解得。 所以这题的解法应该是要用位运算。首先强调一点,Java中int类型的数值2进制为32位。 思想:除了A,其他每一个数都出现3次,所以这些数的二进制对应的每一位加起来,要不是3,要不是0,反正都是能被3整除的。但是多了一个数A,数A的某位可能是1,可能是0。 是0时,那一位的值总原创 2020-06-19 21:51:59 · 198 阅读 · 0 评论 -
丑数
丑数的定义:丑数分解因子中只能有2,3,5,不能有其他数字。根据定义可知一个丑数是另外一个丑数乘以2,或3,或5得到的。第一个丑数为1. 本题的要求,输入一个正整数n,要求得到按升序排列的第n个丑数 public int getUglyNumber() {} 首先我们 ...原创 2020-05-27 08:53:53 · 145 阅读 · 0 评论