【leetcode】 剑指 Offer学习计划(java版本含注释)(下)

目录

  • 前言
  • 第十六天(排序)
    • 剑指 Offer 45. 把数组排成最小的数(中等)
    • 剑指 Offer 61. 扑克牌中的顺子(简单)
  • 第十七天(排序)
    • 剑指 Offer 40. 最小的k个数(简单)
  • 第十八天(搜索与回溯算法)
    • 剑指 Offer 55 - I. 二叉树的深度(简单)
    • 剑指 Offer 55 - II. 平衡二叉树(简单)*
  • 第十九天(搜索与回溯算法)
    • 剑指 Offer 64. 求1+2+…+n(中等)
    • 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先(简单)
    • 剑指 Offer 68 - II. 二叉树的最近公共祖先(简单)*
  • 第二十天(分治算法)
    • 剑指 Offer 07. 重建二叉树(中等)*
    • 第二十一天(位运算)
    • 剑指 Offer 15. 二进制中1的个数(简单)
    • 剑指 Offer 65. 不用加减乘除做加法(简单)*
  • 第二十三天(数学)
    • 剑指 Offer 39. 数组中出现次数超过一半的数字(简单)
    • 剑指 Offer 66. 构建乘积数组(中等)*
  • 第二十五天
    • 剑指 Offer 29. 顺时针打印矩阵(简单)

前言

该链接的学习计划如下:
剑指 Offer学习计划

上一版本的博文链接如下:
【leetcode】 剑指 Offer学习计划(java版本含注释)(上)

此贴两年前写的,一直在草稿箱里,今天释放出来,后续有时间完善下!(= - =)

第十六天(排序)

剑指 Offer 45. 把数组排成最小的数(中等)

题目:

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

示例 1:

输入: [10,2]
输出: “102”

示例 2:

输入: [3,30,34,5,9]
输出: “3033459”

提示:

0 < nums.length <= 100

说明:

输出结果可能非常大,所以你需要返回一个字符串而不是整数
拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0


思路:

关于这部分的具体核心逻辑代码
可参考如下链接:

剑指 Offer 45. 把数组排成最小的数(自定义排序,清晰图解)

class Solution {public String minNumber(int[] nums) {//新建一个字符数组String []s=new String[nums.length];//遍历每个数组到字符数组中,具体转类型,通过String.valueOf(nums[i]);for(int i=0;i<nums.length;i++){s[i]=String.valueOf(nums[i]);}//通过快排将其排好顺序,运用大小的转换quicksort(s,0,s.length-1);//通过StringBuilder() 添加数组的,之后输出其toString类型StringBuilder res = new StringBuilder();for(int i=0;i<s.length;i++){res.append(s[i]);}return res.toString();}public void quicksort(String [] s,int l,int r){if(l>=r)return ;int left=l;int right=r;//具体快排的方式,主要是通过该逻辑x+y>y+x  则x大于y。如果x+y<y+x  则x小于y// 330 大于 303 。也就是30要排在3的后面。用此逻辑将其快排while(left<right){while(left<right && (s[right]+s[l]).compareTo(s[l]+s[right]) >=0)right--;while(left<right && (s[left]+s[l]).compareTo(s[l]+s[left]) <=0)left++;swap(s,left,right);}swap(s,left,l);quicksort(s,l,left-1);quicksort(s,left+1,r);}public void swap(String [] s,int left,int right){String temp=s[left];s[left]=s[right];s[right]=temp;}
}

剑指 Offer 61. 扑克牌中的顺子(简单)

题目:

从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。

示例 1:

输入: [1,2,3,4,5]
输出: True

示例 2:

输入: [0,0,1,2,5]
输出: True

限制:

数组长度为 5

数组的数取值为 [0, 13] .


思路:

class Solution {public boolean isStraight(int[] nums) {Arrays.sort(nums);//将其数组进行排序int res=0;//只遍历到最后一个for(int i=0;i<4;i++){if(nums[i]==0){res++;//统计大小王的数量}//如果有重复的提前返回falseelse if(nums[i+1]==nums[i])return false;}//用最后一个值减去 最小值(除了0),如果小于5则是顺子return nums[4]-nums[res]<5;}
}

或者直接比较最大值最小值即可

class Solution {public boolean isStraight(int[] nums) {Set<Integer> repeat=new HashSet<>();int max=Integer.MIN_VALUE;int min=Integer.MAX_VALUE;for(int i=0;i<5;i++) {if(nums[i] == 0) continue; // 跳过大小王max = Math.max(nums[i],max); // 最大牌min = Math.min(nums[i],min); // 最小牌if(repeat.contains(nums[i])) return false; // 若有重复,提前返回 falserepeat.add(nums[i]); // 添加此牌至 Set}return max-min<5;}
}

注意这种写法:

int max=Integer.MIN_VALUE;
int min=Integer.MAX_VALUE;

第十七天(排序)

剑指 Offer 40. 最小的k个数(简单)

题目:

输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

示例 1:

输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]

示例 2:

输入:arr = [0,1,2,1], k = 1
输出:[0]

限制:

0 <= k <= arr.length <= 10000
0 <= arr[i] <= 10000


思路:

可以通过排序,然后在弄,但是复杂度比较高
这道题是简单题
可以使用复杂度比较低一些的
例如
快排

class Solution {public int[] getLeastNumbers(int[] arr, int k) {quicksort(arr,0,arr.length-1);//数组的截取前几个,通过这个函数return Arrays.copyOf(arr,k);}public void quicksort(int [] arr,int l,int r){if(l>=r)return;//记住左右的节点,因为l作为基准,到时候要替换变成有序的元素int left=l;int right=r;while(left<right){while(left<right&&arr[right]>=arr[l])right--;while(left<right&&arr[left]<=arr[l])left++;swap(arr,left,right);}//不要忘记更换基准的元素swap(arr,left,l);//中间节点已经有序,继续排左右两边的子数组就好quicksort(arr,l,left-1);quicksort(arr,left+1,r);}public void swap(int []arr,int left,int right){int temp=arr[left];arr[left]=arr[right];arr[right]=temp;}
}

或者使用大根堆或者小根堆的实现方式
以下使用的是PriorityQueue
大根堆(前 K 小) / 小根堆(前 K 大)

class Solution {public int[] getLeastNumbers(int[] arr, int k) {if (k == 0 || arr.length == 0) {return new int[0];}// 默认是小根堆,实现大根堆需要重写一下比较器。Queue<Integer> pq = new PriorityQueue<>((o1,o2)->(o2-o1));for (int num: arr) {if (pq.size() < k) {pq.offer(num);}else if(num<pq.peek()){pq.poll();pq.offer(num);}}// 返回堆中的元素int[] res = new int[pq.size()];int idx = 0;for(int num: pq) {res[idx++] = num;}return res;}
}

第十八天(搜索与回溯算法)

剑指 Offer 55 - I. 二叉树的深度(简单)

题目:略


思路:

递归:

class Solution {public int maxDepth(TreeNode root) {//从下往上递归,通过递归左右子树,然后将其判断哪个子树大,最后加1。往上遍历即可if(root==null)return 0;int left=maxDepth(root.left);int right=maxDepth(root.right);return Math.max(left,right)+1;}
}

层次遍历,在每一层加1计数即可

class Solution {public int maxDepth(TreeNode root) {if (root == null) {return 0;}Queue<TreeNode> queue = new LinkedList<TreeNode>();queue.offer(root);//为了方便计数每一层size,也就是最大的深度int ans = 0;while (!queue.isEmpty()) {int n = queue.size();for(int i=0;i<n;i++) {TreeNode node = queue.poll();if (node.left != null)queue.offer(node.left);               if (node.right != null)  queue.offer(node.right);}ans++;}return ans;}
}

剑指 Offer 55 - II. 平衡二叉树(简单)*

题目:略


思路:

class Solution {public boolean isBalanced(TreeNode root) {//返回的高度一定是非负整数,如果abs一直大于1,则会有负数的return heigh(root)>=0;}//重新定义一个int类型的函数,主要是为了返回左右子树的最大深度,在中间加一些判断条件public int heigh(TreeNode root){//终止条件判断,如果叶子节点为null,则直接返回0if(root==null)return 0;//从上往下递归遍历,一开始在最下面的一层次遍历int left=heigh(root.left);int right=heigh(root.right);//如果左子树或者右子树为-1.则往上层递归直接变为-1。还有一个abs直接大于1//不要忽略左右子树,某个数为-1的情况,主要是为了方便传递if(left==-1||right==-1||Math.abs(left-right)>1)return -1;//往上返回的左右子树最大的一个,直接加1。递归条件return Math.max(left,right)+1;}
}

第十九天(搜索与回溯算法)

剑指 Offer 64. 求1+2+…+n(中等)

题目:

求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

示例 1:

输入: n = 3
输出: 6

示例 2:

输入: n = 9
输出: 45

限制:

1 <= n <= 10000


思路:

除法不能使用(数学中的求和不可使用)
for不能使用

class Solution {public int sumNums(int n) {int sum=0;for(int i=1;i<=n;i++){sum+=i;}return sum;}
}

那就通过异或或者递归的方式
该题解主要通过k神
具体解释如下:
面试题64. 求 1 + 2 + … + n(逻辑符短路,清晰图解)

class Solution {//定义一个临界值,放于外面,主要是不影响递归的调用int sum=0;public int sumNums(int n) {//x=n>1不可写成n>1因为boolean变量要修饰。//主要大于1,是因为1的时候是终止条件。具体的递归通过sumNums(n-1)boolean x=n>1&&sumNums(n-1)>1;sum+=n;return sum;}
}

剑指 Offer 68 - I. 二叉搜索树的最近公共祖先(简单)

题目:略


思路:

总体通过root不为null,一个个值比较,如果有两者相等或者不统一,直接返回root节点即可

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {while(root!=null){if(root.val>p.val&&root.val>q.val){root=root.left;}else if(root.val<p.val&&root.val<q.val){root=root.right;}else {return root;}}return null;}
}

剑指 Offer 68 - II. 二叉树的最近公共祖先(简单)*

题目:


思路:

关于该题解,可看k神比较全面的题解:
k神题解

在这里插入图片描述

初始条件以及递归条件以及边界值的返回条件是什么
搞清楚逻辑传递即可

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root == null) return null; // 如果树为空,直接返回nullif(root == p || root == q) return root; // 如果 p和q中有等于 root的,那么它们的最近公共祖先即为root(一个节点也可以是它自己的祖先)TreeNode left = lowestCommonAncestor(root.left, p, q); // 递归遍历左子树,只要在左子树中找到了p或q,则先找到谁就返回谁TreeNode right = lowestCommonAncestor(root.right, p, q); // 递归遍历右子树,只要在右子树中找到了p或q,则先找到谁就返回谁if(left == null) return right; // 如果在左子树中 p和 q都找不到,则 p和 q一定都在右子树中,右子树中先遍历到的那个就是最近公共祖先(一个节点也可以是它自己的祖先)else if(right == null) return left; // 否则,如果 left不为空,在左子树中有找到节点(p或q),这时候要再判断一下右子树中的情况,如果在右子树中,p和q都找不到,则 p和q一定都在左子树中,左子树中先遍历到的那个就是最近公共祖先(一个节点也可以是它自己的祖先)else return root; //否则,当 left和 right均不为空时,说明 p、q节点分别在 root异侧, 最近公共祖先即为 root}
}

第二十天(分治算法)

剑指 Offer 07. 重建二叉树(中等)*

题目:

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。


思路:

第二十一天(位运算)

剑指 Offer 15. 二进制中1的个数(简单)

题目:leetcode:剑指 Offer 15. 二进制中1的个数


思路:

public class Solution {// you need to treat n as an unsigned valuepublic int hammingWeight(int n) {int x=1;int sum=0;while(n!=0){//此处记得括号if((n&x)==1){sum++;}//可以将上面一步到位//  sum += n & 1;//本题要求把数字 n 看作无符号数,因此使用 无符号右移 操作//无符号的移动为>>>n=n>>>1;}return sum;}
}

剑指 Offer 65. 不用加减乘除做加法(简单)*

题目:leetcode:剑指 Offer 65. 不用加减乘除做加法


思路:
这道题的题解主要参考k神题解
在这里插入图片描述

class Solution {public int add(int a, int b) {while(b != 0) { // 当进位为 0 时跳出int c = (a & b) << 1;  // c = 进位a ^= b; // a = 非进位和b = c; // b = 进位}return a;}
}

第二十三天(数学)

剑指 Offer 39. 数组中出现次数超过一半的数字(简单)

题目:leetcode:剑指 Offer 39. 数组中出现次数超过一半的数字


思路:
可以用哈希统计 计算

class Solution {public int majorityElement(int[] nums) {Map<Integer, Integer> map = new HashMap<Integer, Integer>();for (int num : nums) {map.put(num,map.getOrDefault(num,0)+1);        }//--//定义最大值int max=Integer.MIN_VALUE;//为了保留getKey的值int x=0;for (Map.Entry<Integer, Integer> entry : map.entrySet()) {if (entry.getValue() > max) {max = entry.getValue();x=entry.getKey();}}return x;//---或者使用如下进行Map.Entry<Integer, Integer> majorityEntry = null;for (Map.Entry<Integer, Integer> entry : counts.entrySet()) {if (majorityEntry == null || entry.getValue() > majorityEntry.getValue()) {majorityEntry = entry;}}return majorityEntry.getKey();}
}

以及另外一种做法:
题解如下:k神题解

class Solution {public int majorityElement(int[] nums) {//相同票数则加1,不同票数减1,如果为0的票数,设置众数为当前int vote=0;int x=0;for(int num:nums){if(vote==0)x=num;vote+= x==num?1:-1;}return x;}
}

剑指 Offer 66. 构建乘积数组(中等)*

题目:leetcode:剑指 Offer 66. 构建乘积数组

大致意思如下:
在这里插入图片描述


思路:

class Solution {public int[] constructArr(int[] a) {if(a.length==0)return new int [0];int []b=new int[a.length];//设置第一个初值为1b[0]=1;//遍历后边的初值条件int temp=1;//计算从前往后的值,维护b【i】这个数组for(int i=1;i<b.length;i++){b[i]=b[i-1]*a[i-1];}for(int i=b.length-2;i>=0;i--){//从后往前的遍历,计算另外一边的值temp *= a[i + 1];b[i] *= temp;}return b;}
}

第二十五天

剑指 Offer 29. 顺时针打印矩阵(简单)

题目:leetcode:剑指 Offer 29. 顺时针打印矩阵


思路:

螺旋 模拟矩阵

class Solution {public int[] spiralOrder(int[][] matrix) {//可能是空数组,所以要多一个判断条件if(matrix.length == 0) return new int[0];int m=matrix.length;int n=matrix[0].length;//个数用来存放其res的总值int []res=new int[m*n];int left=0,right=n-1,top=0,bottom=m-1;//为了更好的定义,配合数组下标,所以统一减个1int num=0,sum=m*n-1;while(num<=sum){for(int i=left;i<=right && num<=sum;i++){res[num++]=matrix[top][i];}top++;for(int i=top;i<=bottom && num<=sum;i++){res[num++]=matrix[i][right];}right--;for(int i=right;i>=left && num<=sum;i--){res[num++]=matrix[bottom][i];}bottom--;for(int i=bottom;i>=top && num<=sum;i--){res[num++]=matrix[i][left];}left++;}return res;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/719308.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLO系列中的“data.yaml”详解!

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、data.yaml介绍 YOLO系列中的data.yaml文件包含了YOLO系列模型运行所需要的数据集路径、数据集中的类别数及标签。数据集路径可以用绝对路径也可以…

如何在飞书接入ChatGPT并结合内网穿透实现公网远程访问智能AI助手

文章目录 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 前言 在飞书中创建chatGPT机器人并且对话&#xff0c;在下面操作步骤中…

GEE代码条带问题——sentinel-1接缝处理的问题

问题 我有兴趣确定 NDVI 损失最大的年份。我创建了一个函数来收集所有陆地卫星图像并应用预处理。当我导出结果以识别 NDVI 损失最大年份时&#xff0c;生成的数据产品与陆地卫星场景足迹有可怕的接缝线。造成这种情况的原因是什么以及如何调整代码&#xff1f; sentinel1数据…

flutter之终极报错

看到这个报错头都大了 一开始在网上各种搜搜&#xff0c;然后有人说是flutter版本的问题&#xff0c;改完版本之后还是不对&#xff0c;又是各种搜搜搜 有人说是环境变量的问题&#xff0c;后来改了环境变量&#xff0c;妈的&#xff0c;竟然还不行&#xff0c;想砸电脑的心都…

Xcode :Could not build module ‘WebKit‘ 已验证解决

问题&#xff1a;Could not build module WebKit 具体报错如下&#xff1a; error: type argument nw_proxy_config_t (aka struct nw_proxy_config *) is neither an Objective-C object nor a block type property (nullable, nonatomic, copy) NSArray<nw_proxy_config_…

C++学习笔记:set和map

set和map set什么是setset的使用 关联式容器键值对 map什么是mapmap的使用map的插入方式常用功能map[] 的灵活使用 set 什么是set set是STL中一个底层为二叉搜索树来实现的容器 若要使用set需要包含头文件 #include<set>set中的元素具有唯一性(因此可以用set去重)若用…

掌握未来技术:一站式深度学习学习平台体验!

介绍&#xff1a;深度学习是机器学习的一个子领域&#xff0c;它模仿人脑的分析和学习能力&#xff0c;通过构建和训练多层神经网络来学习数据的内在规律和表示层次。 深度学习的核心在于能够自动学习数据中的高层次特征&#xff0c;而无需人工进行复杂的特征工程。这种方法在图…

大模型笔记:RAG(Retrieval Augmented Generation,检索增强生成)

1 大模型知识更新的困境 大模型的知识更新是很困难的&#xff0c;主要原因在于&#xff1a; 训练数据集固定,一旦训练完成就很难再通过继续训练来更新其知识参数量巨大,随时进行fine-tuning需要消耗大量的资源&#xff0c;并且需要相当长的时间LLM的知识是编码在数百亿个参数中…

一些C语言知识

C语言的内置类型&#xff1a; char short int long float double C99中引入了bool类型&#xff0c;用来表示真假的变量类型&#xff0c;包含true&#xff0c;false。 这个代码的执行结果是什么&#xff1f;好好想想哦&#xff0c;坑挺多的。 #include <stdio.h>int mai…

STM32(5) GPIO(2)输出

1.点亮LED 1.1 推挽接法和开漏接法 要想点亮LED&#xff0c;有两种接法 推挽接法&#xff1a; 向寄存器写1&#xff0c;引脚输出高电平&#xff0c;LED点亮&#xff1b;向寄存器写0&#xff0c;引脚输出低电平&#xff0c;LED熄灭。 开漏接法&#xff1a; 向寄存器写0&…

《精益DevOps》:填补IT服务交付的认知差距,实现高效可靠的客户期望满足

写在前面 在当今的商业环境中&#xff0c;IT服务交付已经成为企业成功的关键因素之一。然而&#xff0c;实现高效、可靠、安全且符合客户期望的IT服务交付却是一项艰巨的任务。这要求服务提供商不仅具备先进的技术能力&#xff0c;还需要拥有出色的组织协作、流程管理和态势感…

UniApp项目处理小程序分包

目前 uniApp也成为一种 App端开发的大趋势 因为在目前跨端 uniApp可以说相当优秀 可以同时兼容 H5 PC 小程序 APP 的技术 目前市场屈指可数 那么 说到微信小程序 自然就要处理分包 因为微信小程序对应用大小限制非常铭感 限制在2MB 超过之后就会无法真机调试与打包 不过需要注…

vue项目中使用antvX6新手教程,附demo案例讲解(可拖拽流程图、网络拓扑图)

前言&#xff1a; 之前分别做了vue2和vue3项目里的网络拓扑图功能&#xff0c;发现对antv X6的讲解博客比较少&#xff0c;最近终于得闲码一篇了&#xff01; 需求&#xff1a; 用户可以自己拖拽节点&#xff0c;节点之间可以随意连线&#xff0c;保存拓扑图数据后传给后端&…

cPanel面板安装付费的SSL证书

前不久遇到购买Hostease服务器的客户反馈需要安装SSL证书。因为安装 SSL 证书不仅可以保护用户数据安全&#xff0c;增加用户信任度&#xff0c;提升搜索引擎排名&#xff0c;还有助于符合法规和标准&#xff0c;防止网络攻击。 安装SSL证书可以通过如下步骤: 1. 选择 SSL 证书…

数学建模【多元线性回归模型】

一、多元线性回归模型简介 回归分析是数据分析中最基础也是最重要的分析工具&#xff0c;绝大多数的数据分析问题&#xff0c;都可以使用回归的思想来解决。回归分析的任务就是&#xff0c;通过研究自变量X和因变量Y的相关关系&#xff0c;尝试去解释Y的形成机制&#xff0c;进…

Linux配置网卡功能

提示:工具下载链接在文章最后 目录 一.network功能介绍二.配置network功能2.1 network_ip配置检查 2.2 network_br配置2.2.1 配置的网桥原先不存在检查2.2.2 配置的网桥已存在-修改网桥IP检查2.2.3 配置的网桥已存在-只添加网卡到网桥里检查 2.3 network_bond配置检查 2.4 netw…

Access AR Foundation 5.1 in Unity 2022

如果已经下载安装了ARF但版本是5.0.7 可以通过下面的方式修改 修改后面的数字会自动更新 更新完成后查看版本 官方文档 Access AR Foundation 5.1 in Unity 2021 | AR Foundation | 5.1.2

【知识整理】Git 使用实践问题整理

问题1、fatal: refusing to merge unrelated histories 一、Git 的报错 fatal: refusing to merge unrelated histories 新建了一个仓库之后&#xff0c;把本地仓库进行关联提交、拉取的时候&#xff0c;出现了如下错误&#xff1a; fatal: master does not appear to be a g…

电脑无法开启虚拟化

vm开启虚拟化失败 如果出现以下错误&#xff0c;需要进入bios界面&#xff0c;不同电脑进入界面的方式不一样。这里以hp为例&#xff1a; 1、关机后&#xff0c;按住开机键和f10&#xff0c;进入如下界面&#xff08;语言在主菜单里面&#xff09; 2、选择先进和下面的系统选…

c语言游戏实战(10):坤坤的篮球回避秀

前言&#xff1a; 这款简易版的球球大作战是博主耗时两天半完成的&#xff0c;玩家需要控制坤坤在游戏界面上移动&#xff0c;来躲避游戏界面上方不断掉下来的篮球。本游戏使用C语言和easyx图形库编写&#xff0c;旨在帮助初学者了解游戏开发的基本概念和技巧。 在开始编写代…