剑指offer
sunny_daily
java、数据结构、leetcode、企业数字化转型!在线免费接需求!!!
展开
-
65-不用加减乘除做加法
写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。如输入: a = 1, b = 1,输出: 2。 这道题虽然不难,但需要用到位运算。需要用到与和异或运算,“与”表示表示两个都是1,则位1;“异或”表示只有不同才为1,相同则为0。将整数转为二进制,实际动手测试一下即可。其中Integer.toBinary(value)方法,可以将value转为二进制。package leecodeOff;/* * 65.不用加减乘除...原创 2021-09-18 21:25:53 · 93 阅读 · 0 评论 -
15-二进制中1的个数
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量).)。提示:请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。如输入:n = 11 (控制台输入 00000000000000000000000000001011),输出:3...原创 2021-09-18 20:23:29 · 96 阅读 · 0 评论 -
33-二叉搜索树后序遍历
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。如输入: [1,6,3,2,5] ,输出: false。 如果一棵树是二叉搜索树,则对每一个非叶子节点来讲,其左节点肯定小于该节点,其右节点的值大于该节点。设输入的后续遍历数组为postorder,数组长度为n,则其最后一个节点肯定是根节点。从左到右对数组进行遍历,找到连续的小于postorder[n-1]的节点,假设前i个元素...原创 2021-09-18 20:14:28 · 91 阅读 · 0 评论 -
07-根据前序和中序重构二叉树
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。如输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7],输出: [3,9,20,null,null,15,7]。 前序遍历是指根、左、右的顺序进行遍历,中序是指左、中、右进行遍历。所以前序遍历priorder的第一个节点肯定就是整个二叉树的根节点。根据第一个节点找到该值在inorder的位置,就可以...原创 2021-09-18 15:53:57 · 107 阅读 · 0 评论 -
68-普通二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”如输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1,输出: 3,节点 5 和节点 1 的最近公共祖先是节点 3。 对二叉树从下往上进行遍历。假设当前遍历的节点为temp节点...原创 2021-09-18 11:20:39 · 129 阅读 · 0 评论 -
61-扑克牌中的顺子
从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。如输入: [1,2,3,4,5] 输出: True;输入: [0,0,1,2,5] 输出: True。 根据题意其实就是给一个含有五个元素的数组,数组的元素是从0到13之间。判断数据元素是不是连续即可,但这里有一个特征...原创 2021-09-17 22:22:09 · 53 阅读 · 0 评论 -
68-二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。如输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8;输出: 6 。解释: 节点 2 和节点 8 的最近公共祖先是 6。 既然给定的是二叉搜索树,则意味着树的左节点的值小...原创 2021-09-17 22:17:25 · 162 阅读 · 0 评论 -
55-平衡二叉树
输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。如给定二叉树[3,9,20,null,null,15,7],返回true。 力扣把这道题划分为简单,但个人感觉也不是很简单。这里需要计算树的高度,如果高度差在1之内,可以理解为平衡二叉树,所以需要从底向上进行遍历,如果返回的是-1,则意味着不是平衡二叉树。二叉树还是不太好理解,要常常复习。package leecodeOff;/* * ...原创 2021-09-17 21:12:19 · 115 阅读 · 0 评论 -
49-数组中出现次数超过一半的数字
剑指offer的第49道题。数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。如输入: [1, 2, 3, 2, 2, 2, 5, 4, 2],输出: 2。 这道题应该很简单,直接拉一个map哈希对象即可,个人认为这种写法应该是不错的,但提交到力扣之后,感觉效率有点低,希望后续有更好的实现方式。package learnproject.offer;import java.util.HashMap;...原创 2021-09-16 23:19:46 · 52 阅读 · 0 评论 -
55-二叉树的深度
输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。如给定二叉树[3,9,20,null,null,15,7],返回深度为3。 要计算二叉树的深度,从根节点出发,则深度的最大值为左子树的深度加1和右子树深度加1的最大值。因此,采用递归方法来做。假设函数f(node),表示的是根节点为node树的最大深度,则f(head) = Math.min(f(head.left),f(head.right))+1。实现...原创 2021-09-16 22:52:25 · 65 阅读 · 0 评论 -
40-最小的k个数
输入整数数组arr,找出其中最小的k个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。如输入:arr = [3,2,1], k = 2 输出:[1,2] 或者 [2,1]。 直接对数组进行排序,排序结束之后再取出前k个数即可。package learnproject.offer;import java.util.Arrays;/* * 40.最小的k个数 */public class Demo40 {...原创 2021-09-16 20:24:15 · 51 阅读 · 0 评论 -
45-把数组排程最小的数字
剑指offer的第45道题:输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。如输入: [3,30,34,5,9] 输出: "3033459"。输出结果可能非常大,所以你需要返回一个字符串而不是整数,拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0。 要想最后得要的数字最小,则要求拼接的字符串值最小。说到底其实还是一个排序问题,只不过不是普通的排序问题。这里需要比较的是两个数组合起来的大小。假设数组为[a,b,c,d,e,f]。我们...原创 2021-09-16 20:11:02 · 197 阅读 · 0 评论 -
54-二叉搜索树的第k大节点
剑指offer的第54道题,给定一棵二叉搜索树,请找出其中第k大的节点。 根据给出的样例数据,可以得出给出的二叉树是满足中序遍历递增序列的。按左、中、右进行遍历的时候是正序,那么按右、中、左进行遍历,则是逆序。因此本次要求找到第k大的节点,则意味着要逆序找到第k个元素。所以定义一个变量i用来记录第i个元素,定义一个value用来记录第k个元素的值。当对二叉树进行遍历的时候,如果i=k时,此时对value,进行赋值。也因此,如果value>0,则意味着循环结束了。具体代...原创 2021-09-15 23:39:01 · 230 阅读 · 0 评论 -
36-二叉搜索树和双向链表
剑指offer的第36道题。输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。 从题意中可以看出,给出的二叉树是中序递增的,因此要形成一个排序的双向循环链表,要复用二叉树的中序递增特性。在对二叉树节点访问过程中,我们可以采用中序遍历的方法从小到达方位二叉树的节点。在构建相邻节点引用关系时,假设当前节点为cur节点,前置节点为pre节点,则pre.right = cur,cur.left = pre。同时表头...原创 2021-09-15 22:59:40 · 61 阅读 · 0 评论 -
34-二叉树中和为某一值的路径
输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。 本题要求的是从根节点到叶子节点的路径,所以满足条件的list集合,肯定第一个节点是根节点,最后一个节点是叶子节点。学习了力扣上大佬的解题思路,很巧妙。首先定义一个全局变量LinkedList<List<Integer>> list作为返回的所有路径的即可,再定义LinkedList<Integer> subl...原创 2021-09-15 21:53:19 · 46 阅读 · 0 评论 -
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。请问该机器人能够到达多少个格子? 如输入:m = 2, n = 3, k = 1 ,输出:3;输入m = 38,n = 15,k = 9,输出...原创 2021-09-15 17:32:51 · 111 阅读 · 0 评论 -
12-矩阵中的路径
给定一个m x n 二维字符网格board 和一个字符串单词word 。如果word 存在于网格中,返回 true ;否则,返回 false 。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。如输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED";输出:true ...原创 2021-09-14 23:51:50 · 53 阅读 · 0 评论 -
58-翻转单词顺序
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。 这道题难度不高,但就是中间到处有空格,很容易就踩坑,然后就报错了。例如输入"I am a student. ",这个只有后面有空格,直接trim函数即可;如果输入"a good example",两个字符之间有空格,这就需要遍历到对应单词的时候把空格去掉,因此需要将字符串转...原创 2021-09-14 21:15:50 · 242 阅读 · 0 评论 -
力扣57-和为s的两个数字
输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。如输入:nums = [2,7,11,15], target = 9 输出:[2,7] 或者 [7,2]。 这道题比较简单,不复杂。定义两个指针left,right,分别从左到右、从右到左进行遍历。如果和大于目标值,则右指针左移,如果小于目标值,则左指针右移。package leecodeOff;import java.util.Arrays;...原创 2021-09-14 20:12:24 · 44 阅读 · 0 评论 -
力扣21-调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。如输入:nums =[1,2,3,4] 输出:[1,3,2,4]。 这道题比较简单,定义两个指针left、right,分别从左往右、从右往左遍历,如果左边的元素left的值是基数,则left++,如果left的值为偶数,则对right对应的值进行判断,如果为奇数,则交换同时left++、right--,否则将right--。package leecod...原创 2021-09-14 19:41:03 · 124 阅读 · 0 评论 -
52-两个链表的第一个公共节点
输入两个链表,要求找到两个链表的第一个公共节点。如输入listA = [0,9,1,2,4], listB = [3,2,4],则公共节点为值为2的节点。 在求解过程中,如果不考虑空间复杂度可以直接定义一个hashmap,key为节点的值,value为对应节点,先对list1遍历,再对list2遍历,空间复杂度为O(n);如果要求空间复杂度为O(1),则可以定义两个指针,分别指向list1和list2,然后分别同步移动两个指针,直到所指向的节点的值相同。例如l1指针指向li...原创 2021-09-14 19:25:02 · 51 阅读 · 0 评论 -
25-合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。如输入:1->2->4, 1->3->4;输出:1->1->2->3->4->4。 解析的过程中,需要关注两个点:1.将两个链表合并成一个链表;2.新合并的链表也要符合递增。在初始化的时候先虚拟化出一个节点,作为新的链表的头节点(node),再定义一个指针cur指向node节点。然后对l1和l2链表分别进行遍历,找到l1和l2链表头节点值小的节点,...原创 2021-09-14 10:01:20 · 557 阅读 · 0 评论 -
22-链表中倒数第二个节点
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。 样例代码是用hashMap实现了,在力扣中运行的时候发现效率和内存空间占用都比较大,但时间复杂度其实也是O(n)。如果想要更低的空间复杂度可以用两个循环,第一个循环遍历找到ListNode的长度为n,第二次循环的时候,就需要和输...原创 2021-09-13 00:49:52 · 638 阅读 · 0 评论 -
18-删除链表的节点
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。如输入: head = [4,5,1,9], val = 5 输出: [4,1,9]。 要删除单链表上的某一个固定节点,则首先需要找到该节点,然后将该节点的后置节点挂到该节点的前节点上即可。因此,只需要定义两个变量,分别表示节点的前置节点和后置节点,对节点进行遍历,当满足条件时,则break掉中断循环。package learnproject.offer;/* * 18 ...原创 2021-09-13 00:14:42 · 91 阅读 · 0 评论 -
46-把数字翻译成字符串
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。如输入: 12258 输出: 5 给定一个数字,从个位数即最右边开始遍历,遍历第一位时,肯定只有一种翻译方法。在遍历十位数时,就需要考虑,十位数和个位数是单独一个数字翻译成一个字符,还是十位数和个位数组合在一起翻译成一个字符。如果是各自翻译成一个字符,则只要...原创 2021-09-12 13:58:28 · 71 阅读 · 0 评论 -
48-最长不含重复字符的子字符串
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。如输入: "abcabcbb" 输出: 3。 提供了两种解决办法,一个是官方提供的答案,虽然简洁,但感觉不太容易看懂;另外一种是双指针,比较容易看懂,但代码比较复杂。两种方法总体效率差不了太多。package learnproject.offer;import java.util.HashMap;import java.util.Map;/* * 48.最长不含重复字符的子字符串...原创 2021-09-12 13:14:02 · 137 阅读 · 1 评论 -
47-礼物的最大值
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?如输入:int[][] grid = {{1,2,5},{3,2,1}};输出: 12 感觉这些题在刷力扣题库的时候都遇到过,这里直接贴代码出来吧。package learnproject.offer;/* * ...原创 2021-09-12 03:18:31 · 183 阅读 · 0 评论 -
42-连续子数组的最大和
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。如输入: nums = [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 这道题比较简单,只需要用两个参数dp和max,dp用来记录遍历到第i个节点时和的最大值。max用来记录遍历过程中的最大值。属于动态规划算法比较基础的应用。package learnproject.offer;/* * 42.连续子数组最大和 */public clas...原创 2021-09-12 02:44:49 · 57 阅读 · 0 评论 -
63-股票的最大利润
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?如输入: [7,1,5,3,6,4] 输出: 5。 这里有个前提条件就是股票只能买卖一次。具体解析见代码package learnproject.offer;/* * 63.股票的最大利润 */public class Demo63 { /* * 输入:[7,1,5,3,6,4] * 输出:5 * 股票还能买卖一次,当遍历到...原创 2021-09-12 02:28:59 · 60 阅读 · 0 评论 -
10-青蛙跳台阶问题
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n级的台阶总共有多少种跳法。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。青蛙每次只能向上跳1级或两级,在青蛙跳到第n个台阶时,只可能是从第n-1个台阶跳上去或者是从第n-2个台阶跳上去的,就可以直接转成求斐波那契数问题,只不过这里f0=1,f1=1。具体解决过程参考代码。package learnproject.offer;/* * ...原创 2021-09-12 01:56:12 · 370 阅读 · 0 评论 -
28-对称的二叉树
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。例如,二叉树[1,2,2,3,4,4,3] 是对称的;但是[1,2,2,null,3,null,3] 则不是镜像对称的。 要想得到对称的二叉树,则要求左边节点的左子节点和右边节点的右子节点相同;左边节点的右子节点和右边节点的左子节点相同。用递归的方式求解。package learnproject.offer;/* * 28.对称二叉树 */public class...原创 2021-09-12 01:48:30 · 48 阅读 · 0 评论 -
27-二叉树的镜像
请完成一个函数,输入一个二叉树,该函数输出它的镜像。如输入:root = [4,2,7,1,3,6,9];输出:[4,7,2,9,6,3,1],具体树结构如下:package learnproject.offer;import java.util.ArrayList;import java.util.Arrays;import java.util.LinkedList;import java.util.List;import java.uti...原创 2021-09-11 19:53:56 · 60 阅读 · 0 评论 -
26-树的子结构
输入两棵二叉树A和B,判断B是不是A的子结构。事先约定空树不是任意一个树的子结构。如果B是A的子结构, 即 A中有出现和B相同的结构和节点值。 写的代码比标准代码要啰嗦一些,但比较容易看懂。这里将深度优先和广度优先算法都贴出来了。package learnproject.offer;import java.util.LinkedList;import java.util.Queue;/* * 26.树的字结构 */public class Demo26...原创 2021-09-11 18:22:14 · 48 阅读 · 0 评论 -
32-从上到下按层之字形打印二叉树
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。例如给定二叉树:[3,9,20,null,null,15,7];输出[ [3], [20,9], [15,7] ]。 按之字形打印,只需要能区分打印哪一层需要反转即可。因此引入一个flag变量,用来标记是否需要反转,同时集合采用LinkedList集合,支持从前或从后添加元素。package learnproject....原创 2021-09-11 16:47:38 · 71 阅读 · 0 评论 -
32-从上到下按层打印二叉树
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。如:给定二叉树:[3,9,20,null,null,15,7];输出[ [3], [9,20], [15,7] ]。 力扣将这道题归为简单,其实感觉并不是很简单。这里有一个技巧就是要先算出队列的长度,不然无法解析。package learnproject.offer;import java.util.ArrayList;import java.util.Arrays;import j...原创 2021-09-11 16:04:13 · 120 阅读 · 0 评论 -
10-斐波那契数列Ⅰ
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:F(0) = 0,F(1)= 1,F(N) = F(N - 1) + F(N - 2), 其中 N > 1.斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。 这里稍微特殊一点的就是需要做取模运算。...原创 2021-09-11 10:45:15 · 680 阅读 · 0 评论 -
32-从上到下打印二叉树Ⅰ
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。如输入[3,9,20,null,null,15,7];输出[3,9,20,15,7] 解析:打印二叉树的每个节点其实就相当于是做二叉树的广度搜索算法,只能通过队列来实现。package learnproject.offer;import java.util.ArrayList;import java.util.Arrays;import java.util.LinkedList;...原创 2021-09-11 00:29:29 · 63 阅读 · 0 评论 -
50-第一个只出现一次的字符
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。如输入:s = "abaccdeff";输出:'b'。 提供了两种解题思路,firstUniqCharNew方法性能明显比firstUniqChar方法要好。package leecodeOff;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import jav...原创 2021-09-10 20:00:29 · 53 阅读 · 0 评论 -
11-旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组[3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。如输入:[3,4,5,1,2];输出:1 这里需要考虑的就是,数组可能会重复。虽然力扣是放到简单类型,但实际感觉不是很简单,里面还有有一些坑。以下两种方法效率差不多。package leecodeOff;/* * 11.旋转数组的最小数字 */...原创 2021-09-10 19:09:02 · 47 阅读 · 0 评论 -
58-左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。如输入: s = "abcdefg", k = 2;输出: "cdefgab"package leecodeOff;/* * 58 左旋转字符串 */public class Demo58 { public String reverseLeftWords(String s...原创 2021-09-10 16:54:35 · 48 阅读 · 0 评论