剑指
qq_38419093
这个作者很懒,什么都没留下…
展开
-
98. 验证二叉搜索树
题目给定一个二叉树,判断其是否是一个有效的二叉搜索树。满足以下特征:节点的左子树只包含小于当前节点的数。节点的右子树只包含大于当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。方法一: 递归设计一个递归函数 helper(root, lower, upper) 来递归判断public boolean isValidBST(TreeNode root) { return isValidBST(root,Long.MIN_VALUE,Long.MAX_VALUE);原创 2021-07-14 16:30:33 · 49 阅读 · 0 评论 -
24. 两两交换链表中的节点
题目给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。官方方法1递归的终止条件是链表中没有节点,或者链表中只有一个节点,此时无法进行交换。两两交换链表中的节点,原始链表的head变成新的链表的第二个节点,原始链表的第二个节点变成newHead。链表中的其余节点的两两交换swapPairs可以递归地实现,再更新节点之间的指针关系。public ListNode swapPairs(ListNode head) { i原创 2021-07-02 22:19:44 · 87 阅读 · 1 评论 -
206. 反转链表
题目给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。思考假设链表为1→2→3→∅,变成 ∅←1←2←3。在遍历链表时,将当前节点的next 指针改为指向前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。public ListNode reverseList(ListNode head) { while(head==null){ return null; } ListNode cur=hea原创 2021-07-02 21:44:10 · 48 阅读 · 0 评论 -
剑指 Offer 09. 用两个栈实现队列
题目用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )双栈维护两个栈,stack1支持插入操作,stack2支持删除操作。初始化为空。stack1插入元素,若要删除元素,则判断stack2是否为空,若空则将stack1内所有元素弹出插入到stack2中,从stack2中弹出一个元素并返回。class CQueue { De原创 2021-07-02 21:22:16 · 46 阅读 · 0 评论 -
剑指 Offer 07. 重建二叉树
题目输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7]二叉树遍历顺序二叉树前序遍历的顺序为:[ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]先遍历根节点;随后递归地遍历左子树;最后递归地遍历右子树。二叉树中序遍历的顺序为:[ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]先递转载 2021-07-02 20:57:35 · 49 阅读 · 0 评论 -
剑指 Offer 17. 打印从1到最大的n位数
题目输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。解题思路题目要求打印 “从 1 至最大的 n 位数的列表” ,因此需考虑以下两个问题:最大的 n 位数(记为 end )和位数 n 的关系为指数关系;大数越界问题,但是本题返回都为int。 public int[] printNumbers(int n) { int end =(int)Math.pow(10,n)-1; int[]原创 2021-04-21 22:12:21 · 34 阅读 · 0 评论 -
剑指 Offer 16. 数值的整数次方
题目实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,x^n)。不得使用库函数,同时不需要考虑大数问题。解题思路求 x^n最简单的方法是通过循环将 n 个 x 乘起来,依次求 x^1, x^2, …, x^{n-1}, x^n,时间复杂度为 O(n)。快速幂法:可将时间复杂度降低至 O(log_2 n),以下从 “二分法” 和 “二进制” 两个角度解析快速幂法。快速幂解析(二进制角度):利用十进制数字 n 的二进制表示,可对快速幂进行数学化解释。获取二进制各位值,循环执行以下操作即可原创 2021-04-21 22:10:56 · 44 阅读 · 0 评论 -
剑指 Offer 15. 二进制中1的个数
题目请实现一个函数,输入一个整数(以二进制串形式),输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。解题思路方法一:逐位判断根据 与运算 定义,设二进制数字 n ,则有:若n&1=0 ,则 n 二进制 最右一位 为 0 ;若n&1=1 ,则 n 二进制 最右一位 为 1根据以上特点,考虑以下循环判断 :判断 n 最右一位是否为 1 ,根据结果计数。将 n 右移一位(本题要求把数字 n 看作无符原创 2021-04-21 22:00:54 · 39 阅读 · 0 评论 -
剑指 Offer 14- II. 剪绳子
题目给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m - 1] 。请问 k[0]k[1]…*k[m - 1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。解题思路此题与 面试题14- I. 剪绳子 主体等价,不同之处在于“大数原创 2021-04-20 17:38:26 · 63 阅读 · 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。请问该机器人能够到达多少个格子?方法1:广度优先搜索先计算一个数的数位之和,在搜索的过程中搜索方向可以缩减为向右和向下复杂原创 2021-04-20 17:34:06 · 49 阅读 · 0 评论 -
剑指 Offer 12. 矩阵中的路径
题目给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。解题思路本问题是典型的矩阵搜索问题,可使用 深度优先搜索(DFS)+ 剪枝 解决。深度优先搜索: 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另原创 2021-04-18 21:26:03 · 57 阅读 · 0 评论 -
剑指 Offer 11. 旋转数组的最小数字
题目把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。解题思路考虑数组中的最后一个元素 x:在最小值右侧的元素,它们的值一定都小于等于 x;而在最小值左侧的元素,它们的值一定都大于等于 x。因此,我们可以根据这一条性质,通过二分查找的方法找出最小值。在二分查找的每一步中,左边界为 low,右边界为high,区间的中点为 pivot,原创 2021-04-18 21:22:20 · 43 阅读 · 0 评论 -
剑指 Offer 47. 礼物的最大价值
题目在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?解题思路:题目说明:从棋盘的左上角开始拿格子里的礼物,并每次 向右 或者 向下 移动一格、直到到达棋盘的右下角。根据题目说明,易得某单元格只可能从上边单元格或左边单元格到达。可用动态规划解决此问题,转移方程如下f(i,j)=max[f(i,j−1),f原创 2021-04-13 21:05:02 · 48 阅读 · 0 评论 -
剑指 Offer 14- I. 剪绳子
题目给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。解题思路(官方)以下数学推导总体分为两步:① 当所有绳段长度相等时,乘积最大。② 最优的绳段长度为 3。利用“算术几何均值不等式” ,等号当且仅当所有值相等时成立。推论一: 将绳子原创 2021-04-12 21:14:41 · 103 阅读 · 0 评论 -
剑指 Offer 22. 链表中倒数第k个节点
题目输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。解题思路(官方)fast先后移k次,当fast为空时,按链表顺序 slow的后边 有k个(第k个为空) 所以从1开始计数,从后往前第k个是slow。public ListNode getKthFromEnd(ListNode head, int k)原创 2021-04-12 21:11:27 · 80 阅读 · 0 评论 -
剑指 Offer 10- II. 青蛙跳台阶问题
题目一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。public int numWays(int n) { int res =0; if(n==0||n==1){ res=1; } else { int a=1; in原创 2021-04-12 21:08:24 · 45 阅读 · 0 评论 -
剑指 Offer 10- I. 斐波那契数列
题目写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:F(0) = 0, F(1) = 1F(N) = F(N - 1) + F(N - 2), 其中 N > 1.斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。结题思路利用动态规划的方法,以斐波那契数列性质 f(n + 1) = f(n原创 2021-04-12 21:07:15 · 45 阅读 · 0 评论 -
剑指 Offer 06. 从尾到头打印链表
题目输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。方法1:栈:后进先出创建栈存储链表的节点,创建指针初始指向链表的头节点,当指针指向的元素非空时,将指针指向的节点压入栈内,指针移到当前节点的下一个节点。获得栈的大小 size,创建一个数组 print,其大小为 size,创建下标并初始化 index = 0,重复 size 次下列操作:从栈内弹出一个节点,将该节点的值存到 print[index],将 index 的值加 1,返回 print。Stack<ListNode原创 2021-04-06 22:15:34 · 64 阅读 · 0 评论 -
剑指 Offer 05. 替换空格
题目请实现一个函数,把字符串 s 中的每个空格替换成"%20"。方法一:字符数组使用字符数组替换,最多为三倍。获取s长度,创建字符数组,长度三倍,依次遍历并进行替换,最后前size个字符创建为新字符串。int a =s.length(); char[] b =new char[a*3]; int size=0; for(int i=0;i<a;i++){ char c=s.charAt(i); if原创 2021-04-06 21:11:06 · 81 阅读 · 0 评论 -
剑指 Offer 04. 二维数组中的查找
题目在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。[[1, 4, 7, 11, 15],[2, 5, 8, 12, 19],[3, 6, 9, 16, 22],[10, 13, 14, 17, 24],[18, 21, 23, 26, 30]]target = 5第一次题解暴力搜索的方法,直接遍历整个二维数组的每一个元素,判原创 2021-03-24 22:04:57 · 60 阅读 · 0 评论 -
剑指 Offer 03. 数组中重复的数字
数组中重复的数字题目第一次思路官方方法HashSet构造函数添加函数增强for形式题目在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。输入:[2, 3, 1, 0, 2, 5, 3]输出:2 或 3第一次思路用两次遍历寻找具有相同的数字,速度慢class Solution { public int findRepeatNumber(int[] nu原创 2021-03-24 21:20:06 · 117 阅读 · 0 评论