力扣每日一练之二分查找Day10

举报
京与旧铺 发表于 2022/05/27 19:44:55 2022/05/27
【摘要】 力扣每日一练之二分查找Day10🍕前面的话🥞大家好!本篇文章将介绍代码随想录的题,本文将以2道题作为背景,介绍二分查找,展示语言为java(博主学习语言为java)。今天呢,是博主开始刷力扣的第十天,如果有想要开始准备自己的算法面试的同学,可以跟着我的脚步一起,共同进步。大家都是并肩作战的伙伴,一起努力奋力前行,路漫漫其修远兮,吾将上下而求索,相信我们一定都可以拿到自己期望的offer,...

力扣每日一练之二分查找Day10

🍕前面的话🥞

大家好!本篇文章将介绍代码随想录的题,本文将以2道题作为背景,介绍二分查找,展示语言为java(博主学习语言为java)。今天呢,是博主开始刷力扣的第十天,如果有想要开始准备自己的算法面试的同学,可以跟着我的脚步一起,共同进步。大家都是并肩作战的伙伴,一起努力奋力前行,路漫漫其修远兮,吾将上下而求索,相信我们一定都可以拿到自己期望的offer,冲冲冲!

👩‍💻博客主页:京与旧铺的博客主页

✨欢迎关注🖱点赞🎀收藏⭐留言✒

🔮本文由京与旧铺原创,csdn首发!

😘系列专栏:java学习

💻首发时间:🎞2022年5月24日🎠

🎨你做三四月的事,八九月就会有答案,一起加油吧

🔏参考在线编程网站:🎧力扣

🀄如果觉得博主的文章还不错的话,请三连支持一下博主哦

🎧最后的话,作者是一个新人,在很多方面还做的不好,欢迎大佬指正,一起学习哦,冲冲冲

🏓导航小助手📻


图片


🍞Leetcode 367.有效的完全平方数

给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。

进阶:不要 使用任何内置的库函数,如 sqrt 。


 示例 1:
 ​
 输入:num = 16
 输出:true
 示例 2:
 ​
 输入:num = 14
 输出:false

🌮源代码

 class Solution {
     public boolean isPerfectSquare(int num) {
          int left=0,right=num;
          while(left<=right){
              int mid=left+(right-left)/2;
              long square=(long)mid*mid;
              if(square<num){
                  left=mid+1;
              }else if(square>num){
                  right=mid-1;
              }else {
                  return true;
              }
          }
          return false;
     }
 }

🎏思路

考虑使用二分查找来优化方法二中的搜索过程。因为 \textit{num}num 是正整数,所以若正整数 xx 满足 x \times x = \textit{num}x×x=num,则 xx 一定满足 1 \le x \le \textit{num}1≤x≤num。于是我们可以将 11 和 \textit{num}num 作为二分查找搜索区间的初始边界。

细节

因为我们在移动左侧边界 \textit{left}left 和右侧边界 \textit{right}right 时,新的搜索区间都不会包含被检查的下标 \textit{mid}mid,所以搜索区间的边界始终是我们没有检查过的。因此,当\textit{left} = \textit{right}left=right 时,我们仍需要检查 \textit{mid} = (\textit{left}+\textit{right}) / 2mid=(left+right)/2。

🌮69. x 的平方根

给你一个非负整数 x ,计算并返回 x算术平方根

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5


示例 1:

 输入:x = 4
 输出:2

示例 2:

 输入:x = 8
 输出:2
 解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。

👸源代码

 class Solution {
     public int mySqrt(int x) {
         if(x==0){
             return 0;
         }
           if(x==1){
               return 1;
           }
           int left=1;
           int right=x/2;
           while(left<right){
               int mid=left+(right-left+1)/2;
               if(mid>x/mid){
                   right=mid-1;
               }else{
                   left=mid;
               }
           }
           return left;
     }
 }

🧈思路

题意分析

这道题要求我们实现平方根函数,输入是一个非负整数,输出也是一个整数; 但是题目当中说:结果只保留整数的部分,小数部分将被舍去。这是什么意思呢?我们分析一下示例。

 示例 1:
 ​
 ​
 输入: 4
 输出: 2
 这是显然的,44 本身是一个完全平方数,2^2 = 42 
 2
 =4。虽然在数学上一个数的平方根有正有负,但是这个题目只要求我们返回算术平方根。
 ​
 示例 2 :
 ​
 ​
 输入: 8
 输出: 2
 因为 88 的平方根实际上是 2.828422.82842,题目要求我们将小数部分舍去。因此输出 22。于是我们知道:由于输出结果的时候,需要将小数部分舍去,因此问题的答案,平方以后一定不会严格大于输入的整数。这里返回 33 就不对了,这是因为 3^2 = 9 > 83 
 2
 =9>8。


思路分析 从题目的要求和示例我们可以看出,这其实是一个查找整数的问题,并且这个整数是有范围的。

如果这个整数的平方 恰好等于 输入整数,那么我们就找到了这个整数; 如果这个整数的平方 严格大于 输入整数,那么这个整数肯定不是我们要找的那个数; 如果这个整数的平方 严格小于 输入整数,那么这个整数 可能 是我们要找的那个数(重点理解这句话)。 因此我们可以使用「二分查找」来查找这个整数,不断缩小范围去猜。

猜的数平方以后大了就往小了猜; 猜的数平方以后恰恰好等于输入的数就找到了; 猜的数平方以后小了,可能猜的数就是,也可能不是。 很容易知道,题目要我们返回的整数是有范围的,直觉上一个整数的平方根肯定不会超过它自己的一半,但是 00 和 11 除外,因此我们可以在 11 到输入整数除以 22 这个范围里查找我们要找的平方根整数。00 单独判断一下就好。

对代码编写逻辑的解释:

一、写 if 和 else 的原因:

猜的数是 mid ,根据上面的分析,如果 mid 的平方 严格大于 x,mid 肯定不是解,比 mid 大的整数也肯定不是解,因此问题的答案只可能存在区间 [left..mid - 1],此时设置 right = mid - 1; else 的情况就是 if 的反面,只要 if 的分支和对应的区间分析对了,else 的区间是 [left..mid - 1] 的反面区间,即 [mid..right] ,此时设置 left = mid。 二、为什么最后返回 left。

退出 while (left < right) 循环的时候,由于边界搜索是 left = mid 与 right = mid - 1,因此退出循环的时候一定有 left 与 right 重合,返回 right 也可以。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。