来自:码农田小齐

算法将是我今后更新的重点,因为我个人非常喜欢。。而且面试考它啊!有人说刷题没有用,但是你做了题就能感受到 coding 能力的提升和对语言熟悉度的提升。新的一年,每日一题,我们一起进步一起NB!

今天第一题选了我最喜欢的也是折磨了我很久的但并不算难的题目,最终是因为在 GS 电面中被问到了,我才痛下决心把这类题目一网打尽。

先来看最基本版的题目:Leetcode 153题

题干是给了一个【本来排好序了的 且为升序】的数组,然后又在某个不知道的位置旋转了一下,所谓旋转,就是把前面那堆数移到后面来了,求新数组的最小值。比如:

原 array:[0, 1, 2, 4, 5, 6, 7]

rotate 之后就是:[4, 5, 6, 7, 0, 1, 2]

输出:最小值 0

解法一:

Brute Force 暴力解法就是每个数都过一遍,然后用一个变量记录我们见到过的最小值并随时更新。(这个应该都会吧,不会的话可以后台留言告诉我。。请让我看到你。。)

Time complexity = O(n),因为每个数都过了一遍;

Space complexity = O(1),因为只用了有限几个变量。

解法二:

在 O(n) 的基础上我们还想优化,那方向是 O(logn),再想想查找类算法的很容易想到了 binary search。

binary search 的做法就是每轮排除一半,留下另一半是包含正确答案的,再不断缩小范围,把答案找出来。那么解决的关键就在于如何杀掉这一半而不能把答案误杀了。中文叫二分查找,我认为翻译的挺好的,因为只有一次分两份,去掉一份,才能保证时间复杂度是 O(logn)。(此处不懂可以后台留言给我,我会根据反馈在之后的文章补充。)

那么二分查找题目的考点就在于如何排除掉这一半了,一般是通过比较中间的数和左右两端或者目标值的关系,但没有统一的规律,否则还考啥?只能多见多去领悟其精髓,我会在更新完所有 binary search 的题目之后做个总结。

就这一题来说,我们比较 array[mid]array[left] or array[right] 的大小关系,哪边都行。

方法一、先看和右边的比较

  • 如果 array[mid] > array[right],如下图例子,7 比 2 要大,这是不正常的(不升序)的,说明最小值在右边,所以排除左边以及 mid(array[mid] 已经比 array[right] 大了,不可能为最小值),所以

    • left = mid + 1;

  • 如果 array[mid] < array[right](没有=,因为没有duplicates),说明右边是 sorted 的,说明最小值在左边甚至可能就是 mid 本身,所以

    • 所以 right = mid。

  • while终止条件是 left == right 的时候,此时 mid = left = right,返回nums[left] = nums[right] 都行。

// Java
class Solution{public int findMid(int[] nums) {if(nums == null || nums.length == 0) {return -1; // discuss with interviewer}int left = 0;int right = nums.length - 1;while(left < right) {int mid = left + (right - left)/2;if(nums[mid] > nums[right]) {left = mid + 1;} else {right = mid;}}return nums[left];}
}
/*
Runtime: 0 ms, faster than 100.00% of Java online submissions for Find Minimum in Rotated Sorted Array.
Memory Usage: 38.5 MB, less than 79.54% of Java online submissions for Find Minimum in Rotated Sorted Array.
*/

方法二、再看和左边比较

  • 如果 array[mid] >= array[left](这里可能=,因为 mid 可能就是 left;而 mid 不可能是 right,因为 Java 向0取整且如果 left = right 就跳出循环了),那么左边是 sorted 的,最小值在右边(题目说一定 rotated 了),所以 left = mid + 1,但有两点要注意:

    注意⚠️:最小值有可能就是 left,虽然最初数组是 rotate 了,但是在减半之后有可能就是完整 sorted 的

    • 所以此方法还要加一步:最开始先判断是否是sorted的,即array[left] vs array[right]

    注意⚠️:array[mid] = array[left] 时,只剩2个元素,且上一步判断过了这2个元素并非升序,所以最小值是 array[right],所以需要移动 left = mid+1。和 right 比较不需要,因为 mid 不会等于 right。

  • 如果 array[mid] < array[left],那么右边是 sorted 的,最小值在左边甚至是 mid 本身,所以 right = mid。

  • while loop 条件同上

// Java
class Solution {public int findMid(int[] nums) {int left = 0;int right = nums.length - 1;while(left < right) {if(nums[left] < nums[right]) { //⚠️return nums[left];}int mid = left + (right - left)/2;if(nums[mid] >= nums[left]) { //⚠️left = mid + 1;} else {right = mid;}}return nums[left];}
}
/*
Runtime: 0 ms, faster than 100.00% of Java online submissions for Find Minimum in Rotated Sorted Array.
Memory Usage: 38.6 MB, less than 77.27% of Java online submissions for Find Minimum in Rotated Sorted Array.
*/

这题说完了。

Follow up 是154题,可能有 duplicates 的情况。大家可以稍作思考再往下看。

基本思路和上一题一样,但是 [3, 3, 1, 3] 不work,因为当 mid = right 时,无法判断最小值到底在哪边,所以只能一步步走,worst case O(n) 避免不了。

// Java
class Solution {public int findMin(int[] nums) {int left = 0;int right = nums.length - 1;while(left < right) {int mid = left + (right - left)/2;if(nums[mid] > nums[right]) {left = mid + 1;} else if (nums[mid] == nums[right]) {right --;} else {right = mid;}}return nums[left];}
}
/*
Runtime: 0 ms, faster than 100.00% of Java online submissions for Find Minimum in Rotated Sorted Array II.
Memory Usage: 41.8 MB, less than 6.25% of Java online submissions for Find Minimum in Rotated Sorted Array II.
*/

以上就是 rotate array 中找最小值的完整方法了,明天我们来看在 rotate array 中找一个特定目标值的题目,这题有很多方法,我会分享我认为觉得最好的一种,会对 binary search 的理解更加深刻。

题目:Leetcode 33 & 81

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

「二分查找」之我见!今天刷一道leetcode算法!相关推荐

  1. 去掉数组最后一个元素_leetcode 34. 在排序数组中查找元素的第一个和最后一个位置每天刷一道leetcode算法系列!...

    作者:reed,一个热爱技术的斜杠青年,程序员面试联合创始人 前文回顾: leetcode1. 两数之和--每天刷一道leetcode系列! leetcode2. 两数相加--每天刷一道leetcod ...

  2. leetcode17. 电话号码的字母组合--每天刷一道leetcode算法系列!

    作者:reed,一个热爱技术的斜杠青年,程序员面试联合创始人 前文回顾: leetcode1. 两数之和--每天刷一道leetcode系列! leetcode2. 两数相加--每天刷一道leetcod ...

  3. 常用十大算法 非递归二分查找、分治法、动态规划、贪心算法、回溯算法(骑士周游为例)、KMP、最小生成树算法:Prim、Kruskal、最短路径算法:Dijkstra、Floyd。

    十大算法 学完数据结构该学什么?当然是来巩固算法,下面介绍了十中比较常用的算法,希望能帮到大家. 包括:非递归二分查找.分治法.动态规划.贪心算法.回溯算法(骑士周游为例).KMP.最小生成树算法:P ...

  4. 二分查找基础概念与经典题目(Leetcode题解-Python语言)二分数值型

    二分查找的讲解请见上一篇文章.本文主要记录对数值进行二分的题目解法与思路. 374. 猜数字大小 class Solution:def guessNumber(self, n: int) -> ...

  5. 二分查找基础概念与经典题目(Leetcode题解-Python语言)二分索引型

    二分查找的定义如下(引自Wiki): 在计算机科学中,二分查找算法(英语:binary search algorithm),也称折半搜索算法(英语:half-interval search algor ...

  6. 无序链表(顺序查找)和有序数组(二分查找)-基础实现-符号表(二)-数据结构和算法(Java)

    文章目录 1 无序链表的顺序查找 1.1 无序链表实现 1.2 分析 2 有序数组中的二分查找 2.1 实现 2.2 分析 3 对二分查找的分析 4 总结 5 后记 1 无序链表的顺序查找 1.1 无 ...

  7. 算法学习 |从无到有 刷爆LeetCode算法神器

    开始文章输出之前,我没有着急下笔,而是认真的问了自己几个问题. 我为什么要学算法? 如何保持学习的热情和积极性? 学到的算法是否可以应用到工作中? 学到的算法怎么应用到工作中? 如何实现从掌握到精通? ...

  8. 根可达算法的根_好屌好屌的「GC系列」JVM垃圾定位及垃圾回收算法浅析

    0x01 什么是垃圾 很简单,没有引用指向的任何对象都叫做垃圾(garbage). 什么是garbage 在某一内存空间中,Java程序制造了很多对象被引用,有的对象还引用别的对象,中途有对象不被需要 ...

  9. leetcode2. 两数相加--每天刷一道leetcode系列!

    来自:程序员面试 作者:reed,一个热爱技术的斜杠青年,程序员面试联合创始人 题目描述 给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节 ...

最新文章

  1. Terracotta tc-config.xml配置说明(这个真的是转的)
  2. 记录一下VsCode配置C/C++运行环境
  3. WIN32 使用 MUTEX 实现禁止多开
  4. booloader编写
  5. 210326阶段三人脸识别
  6. 我喜欢的一首歌--《幸福的瞬间》
  7. C++/C 宏定义(define)中# ## 的含义(转)
  8. 智能会议系统(32)---WebRTC学习之三:录音和播放
  9. msys 中打开系统程序
  10. 视频APP软件开发功能架构
  11. 用HTML+CSS做一个漂亮简单的个人网页——樱木花道篮球3个页面 学生个人网页设计作品 学生个人网页模板 简单个人主页
  12. Error occurred during initialization of VM 解决
  13. html验证座机号码_JS校验手机号 座机 邮箱 微信号
  14. 《以幽默的方式过一生》总结1——春
  15. 解决UE4打包Android报错app:packageDebug FAILED的一个土方法
  16. Zookeeper 3.5.7学习记录(一)——集群的坑
  17. oa系统服务器租赁,oa服务器租赁
  18. 隐匿的风暴,Saas海啸正瞄准企业IT业务
  19. 自身知识浅薄,开发积累问题
  20. 记录一下:老衲的py路程 mac下的tkinter小应用

热门文章

  1. 第1关:学习-用循环和数组实现输入某年某月某日,判断这一天一年的第几天
  2. codeforces432D[kmp的next数组的运用]
  3. HDU - 6486 Flower(思维)
  4. 浙江大学计算机经济学院,浙江大学计算机学院来区考察调研
  5. enter对应的keycode_键盘对应数字-keycode值大全
  6. mybatis源码阅读
  7. Promise基础用法
  8. postman设置Cookie上行参数访问接口
  9. 中国首个量子计算机诞生 中科院、阿里巴巴共同研发
  10. 《Unity 4 3D开发实战详解》一6.7 物理引擎综合案例