菜鸟的算法学习之路
Day4
2019年7月29日,因为360浏览器一直出现编辑不了的问题,于是做了几题一直未写博客。这几天开始接触算法中最简单的二分法
一、x的平方根
题目:
计算并返回 x 的平方根,其中 x 是非负整数。
代码:
class Solution { public int mySqrt(int x) { // for(long i=0;i<=x;i++) // { // if(i*i==x) // return (int)i; // if(i*i>x) // return (int)i-1; // } // return x; long left=0,right=x; while(left<right) { long mid=(left+right+1)>>>1; long square = mid*mid; if(square>x) right=mid-1; else left=mid; } return (int)left; } }
思路:
把这题做出来很简单,直接使用暴力法,循环判断出想要的平方根就行,需要注意的是因为题目中给的数可能很大,我们需要将定义的数都变为长整形,其次因为存在0的平方为0,1的平方为1的情况下,我们需要将循环的值从0累加到x。
我们所需要努力的则是尽可能的去减小空间复杂度和时间复杂度,上面的代码示例则是用二分法做的,用二分法可以有效的减少循环次数,在看力扣的解题分析中,发现一篇非常好用且容易理解的二分法讲解,这里贴上网址。
用二分法解题需要注意的点有寻找中位数是找左中位数还是右中位数,左则是mid=left+right>>>1,右则是mid=left+right+1>>>1,还有判断语句后,left是取mid的值还是mid+1的值,这主要是看你的答案是否存在于mid,right是取right的值还是right-1的值同理,下面将会有几个样例为大家举例分析。
此题我首先是用的左中位数做题,如果当前数的平方大于了x,那么这个数肯定不会是我们要求的结果,例如8的平方根为2,所以当right为3的时候,3的平方比9大,3的值肯定不会是我们要求的结果,于是我们将判断语句后写为right=mid-1,left=mid。循环跳出的时候left和right等值,所以返回哪一个都行,这样的运行结果会是陷入死循环,于是我们将中位数取为右中位数。同样我们也可以想一个样例出来代入这个函数中自己去求解,也可以知道是用左中位数还是右中位数。
二、搜索插入位置
学习完二分法后,先前做的这题也可以用二分法做出来,于是把先前的代码注释掉重做了一遍。
题目:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
代码:
class Solution { public int searchInsert(int[] nums, int target) { // for(int i=0;i<nums.length;i++) // { // if(nums[i]>=target) // return i; // } // return nums.length; int left=0,right=nums.length-1; if(nums[nums.length-1]<target) return nums.length; while(left<right) { int mid=left + (right-left)/2; if(nums[mid]<target) left=mid+1; else right=mid; } return left; } }
思路:
用二分法做这题首先我们需要考虑到一种特殊情况,当target比数组里所有的元素都大时,他会排到数组的最后面,于是函数开始我们先用一个判断语句将这种情况排除。然后二分法照搬解题方法,因为target插入的位置左边的元素一定都比target小,则判断语句判断当前元素比target小后,target绝对不会插入到当前位置,肯定是当前位置之后的位置,因此left=mid+1。这个二分法的应用极为简单。
三、第一个错误的版本
题目:
假设你有 n 个版本 [1, 2, …, n],你想找出导致之后所有版本出错的第一个错误的版本。
代码:
/* The isBadVersion API is defined in the parent class VersionControl. boolean isBadVersion(int version); */ public class Solution extends VersionControl { public int firstBadVersion(int n) { int left=0,right=n; while(left<right) { int mid=left+right>>>1; if(isBadVersion(mid)==true){ right=mid; }else{ left=mid+1; } } return left; } }
思路:
二分法的代码照搬,需要思考的仅仅只是left是等于mid还是等于mid+1,若当前中位数的版本为错误的,那么第一个正确的版本肯定在当前中位数的后面,所以left=mid+1;
- 我的算法学习之路1_算法作用
- 我的算法学习之路
- 学习python之路---python小算法总结(三)
- 菜鸟学习之路-------文件与文件系统打包
- [iOS菜鸟的学习之路]定位功能的实现
- 巩朋:我的算法学习之路
- 开启算法学习之路
- 菜鸟Android学习之路27——notification
- 算法学习之路-交换排序
- 算法学习之路
- 算法学习之路——贪心
- 我的算法学习之路
- 算法学习之路:分治策略-最大子数组-java实现
- 小菜鸟的JS学习之路——No.3(数据类型 1)
- 菜鸟Android学习之路13——图片按钮
- 菜鸟的 PHP 学习之路(四):PHP 的数据类型转换
- 菜鸟Android学习之路16——自动补全文本
- 小菜数据结构于算法学习之路
- CocosCreator游戏开发---菜鸟学习之路(一)
- 菜鸟的Hadoop学习之路系列<二>:Hadoop集群构成和HDFS