首先放今天的力扣打卡题。

在第一次做的过程中,我忽略了“升序排列”这个条件,没有使用二分。
由于是最近才刚开始学golang,所以很有兴趣的在这道题里使用了go的大杀器——goroutine。思路就是使用两个goroutine,一个从头到尾遍历数组,找出开始位置,一个倒序遍历数组,找到结束位置。
代码如下:

func searchRange(nums []int, target int) []int {//使用WaitGroup控制goroutinevar wg sync.WaitGroup//wg加入两个任务wg.Add(2)length := len(nums)//将start end直接赋值-1 当找不到时直接返回start := -1end := -1//第一个goroutinego func() {//函数运行结束后wg任务-1defer wg.Done()//正序遍历数组,找到start就跳出for i := 0; i < length; i++ {if nums[i] == target {start = ibreak}}}()go func() {defer wg.Done()//倒序遍历数组,找到end就跳出for i := length-1; i >= 0; i-- {if nums[i] == target {end = ibreak}}}()//wg一直等待两个任务结束wg.Wait()return []int{start,end}
}

由于go出色的性能,结果还是挺令人满意。

在完成这道题后,我去看了看题解,这才发现数组是有序的,可以使用二分法完成。
而官方的Go题解非常简练优雅。
这里放上代码并加上注释。

func searchRange(nums []int, target int) []int {/*SearchInts函数会返回数组中target第一次出现的位置。如果没有找到,则会返回数组长度n。*///找起始位置leftmost := sort.SearchInts(nums, target)if leftmost == len(nums) || nums[leftmost] != target {return []int{-1, -1}}//结束位置(这里是找target+1,比target大一的数字的起始位置就在target结束位置的右边)rightmost := sort.SearchInts(nums, target + 1) - 1return []int{leftmost, rightmost}
}

其中使用到了SearchInts这个函数。
跟踪进去,发现它调用了sort包下的Search函数。
这里对这个使用二分进行查找的函数进行分析。

func Search(n int, f func(int) bool) int {i, j := 0, nfor i < j {/*这里使用了移位操作,其结果与(i+j)/2一样。uint是无符号的int,范围是2^32即0到4294967295。使用uint可以避免因为i+j太大而造成的溢出*/h := int(uint(i+j) >> 1)// 如果f(h)返回false,说明从i到h中没有目标值。这时更新i为h+1 从原先的i到现在的i之间的数就不会再次扫描了 //相反的,如果f(h)返回true,说明从i到h中有目标值。这时更新j为 hif !f(h) {i = h + 1 } else {j = h // preserves f(j) == true}}//当 i==j 时,说明找到了(或者找完了但是没有找到,这时返回的是数组长度)return i
}

在阅读这段简单的源码时,其中的移位操作很有趣。在此之前,我并不知道还可以使用移位来进行/2的操作。其中原理也很简单:
在二进制中,每一位等于前面所有位的值之和再加一。
例如,7位二进制的最大值为1111111,即127。
给它加一即为10000000,128。

因此,对数字向右移位一位,就是其/2的结果。

而在查资料的时候,发现移位实现的乘除法比直接乘除的效率高很多。
总结:
1.遇到查找有序数组中的元素的时候应该反应出来使用二分。
2.遇到需要大量进行乘除法的操作时,考虑使用移位。

Golang sort包Search函数源码分析相关推荐

  1. PHP 源码 —— is_array 函数源码分析

    is_array 函数源码分析 本文首发于 https://github.com/suhanyujie/learn-computer/blob/master/src/function/array/is ...

  2. 【Linux 内核 内存管理】物理分配页 ⑨ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | retry 标号代码分析 )

    文章目录 一.retry 标号代码分析 二.retry 标号完整代码 在 [Linux 内核 内存管理]物理分配页 ② ( __alloc_pages_nodemask 函数参数分析 | __allo ...

  3. 【Linux 内核 内存管理】物理分配页 ⑧ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | 获取首选内存区域 | 异步回收内存页 | 最低水线也分配 | 直接分配 )

    文章目录 一.获取首选内存区域 二.异步回收内存页 三.最低水线也分配 四.直接分配内存 在 [Linux 内核 内存管理]物理分配页 ② ( __alloc_pages_nodemask 函数参数分 ...

  4. vxworks环形缓冲区函数源码分析

    VxWorks环形缓冲区函数源码分析 ​ by zn 文章目录 VxWorks环形缓冲区函数源码分析 0.使用环形缓冲区的注意事项 1.环形缓冲区结构体定义 2.rngCreate--创建环形缓冲区 ...

  5. 【SA8295P 源码分析】22 - QNX Ethernet MAC 驱动 之 emac_entry / emac_attach 函数源码分析

    [SA8295P 源码分析]22 - QNX Ethernet MAC 驱动 之 emac_entry / emac_attach 函数源码分析 一.EMAC:libdevnp-emac-eth.so ...

  6. 【Linux 内核】实时调度类 ⑦ ( 实时调度类核心函数源码分析 | dequeue_task_rt 函数 | 从执行队列中移除进程 )

    文章目录 一.dequeue_task_rt 函数 ( 从执行队列中移除进程 ) 二.update_curr_rt 函数 ( 更新调度信息 ) 本篇博客中 , 开始分析 struct sched_cl ...

  7. 【Linux 内核】实时调度类 ⑥ ( 实时调度类核心函数源码分析 | 插入进程到执行队列 | 从执行队列中选择优先级最高的进程 )

    文章目录 一.enqueue_task_rt 函数 ( 插入进程到执行队列 ) 二.pick_next_task_rt 函数 ( 从执行队列中选择优先级最高的进程 ) 本篇博客中 , 开始分析 str ...

  8. 【Linux 内核 内存管理】物理分配页 ⑦ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | 判断页阶数 | 读取 mems_allowed | 分配标志位转换 )

    文章目录 一.__alloc_pages_slowpath 慢速路径调用函数 二.判断页阶数 三.读取进程 mems_allowed 成员 四.分配标志位转换 五.__alloc_pages_slow ...

  9. is array php,PHP 源码 — is_array 函数源码分析

    php 中的 is_array php 中的 is_array,它的签名是 is_array ( mixed $var ) : bool 实现的源码 在\ext\standard\type.c中可以找 ...

最新文章

  1. 中央空调如何调节温度html,中央空调怎么调温度
  2. hihocoder#1041 : 国庆出游(DFS)
  3. Angular(build打包)报错:supplied parameters do not match any signature of call target
  4. 登录,注册,登录,登录..?
  5. java之for循环
  6. 我什么时候应该使用访客设计模式? [关闭]
  7. 309. 最佳买卖股票时机含冷冻期
  8. 前端知识 之 HTML
  9. Python解微分方程(验证数学建模第五版火箭发射模型)
  10. 自然语言处理(NLP)常用算法入门笔记
  11. 第6章 Python 数字图像处理(DIP) - 彩色图像处理1 - RGB彩色模型,RGB to Gray,CMK和CMYK彩色模型,HSI彩色模型
  12. 根据图像匹配实现鼠标自动点击
  13. OSWorkflow(转载)
  14. (以三星S8为例)安卓全面屏手势设置教程
  15. java+上传整个文件夹的所有文件
  16. ChatGPT使用拓展资料:AI大模型之美 -客户服务、聊天机器人和情感分析
  17. inter-因特尔-官网
  18. linux系统线程通信的几种方式,Linux进程间通信-线程间通信
  19. oracle 指定账套建表,FAQ-EAS账套备份恢复方法(oracle)
  20. 测试环境部署——selenium+python

热门文章

  1. Python批量导入图片到Word文件
  2. python行程风险测评系统
  3. SDN和NFV并没有迅速落地的原因是什么?
  4. R语言案例分析:多元数据的基本统计分析
  5. TypeError: torch.FloatTensor is not a Module subclass
  6. Numpy 中的矩阵向量乘法
  7. (视频) 《快速创建网站》3.4 网站改版3分钟搞定 - WordPress主题安装和备份
  8. 单核CPU仍然存在线程安全问题
  9. OTL、OCL、BTL电路的区别及其判断方法
  10. Android吃鸡 3dtouch,绝地求生刺激战场3Dtouch怎么用 3Dtouch设置攻略