数据结构与算法--查找与排序另类用法-旋转数组中的最小数字
生活随笔
收集整理的這篇文章主要介紹了
数据结构与算法--查找与排序另类用法-旋转数组中的最小数字
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
查找與排序
查找
- 查找與排序都在程序設(shè)計(jì)中常被用到的算法。查找相對(duì)而言簡(jiǎn)單,一般都是順序查找,二分查找,哈希表查找,和二叉排序樹查找。其中二分查找是我必須熟悉的一種。
- 哈希表和二叉排序樹主要點(diǎn)在于他的數(shù)據(jù)結(jié)構(gòu)而不是算法。哈希表主要的優(yōu)點(diǎn)是我們利用他能在O(1)的時(shí)間查找某個(gè)元素,是效率最高的查找方式。但是缺點(diǎn)是需要額外空間來(lái)實(shí)現(xiàn)哈希表
- 二叉排序樹查找算法對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)是二叉搜索樹(或者叫二叉查找樹),之前我們已經(jīng)著重討論過(guò)這種數(shù)據(jù)結(jié)構(gòu)原理以及自己的實(shí)現(xiàn)。
排序
- 排序比查找要復(fù)雜,例如經(jīng)常選擇一種排序算法的時(shí)候經(jīng)常會(huì)對(duì)各種排序算法進(jìn)行比較:插入排序,冒泡排序,歸并排序,快速排序等不同算法的優(yōu)劣。而這些都是必須掌握的排序算法,我們必須能從空間福再度,時(shí)間復(fù)雜度等方面去分析他們的優(yōu)缺點(diǎn)。其中快速排序是重中之重。可見的幾種排序算法在之前的章節(jié)中也用動(dòng)圖的方式給出來(lái)詳細(xì)的解釋,實(shí)現(xiàn)。
實(shí)際案例
- 快排是重要的排序算法,但是在具體場(chǎng)景下我們需要選擇最優(yōu)最合適的算法,例如下情況:
- 實(shí)現(xiàn)一個(gè)排序算法,實(shí)際復(fù)雜度,空間復(fù)雜度必須不超過(guò)O(n),對(duì)公司所有員工年齡進(jìn)行排序。
- 分析上題中,重點(diǎn)空間復(fù)雜度,實(shí)際復(fù)雜度O(n)
- 排序?qū)ο?#xff0c;員工年齡,我們假設(shè)員工都是100 歲以下,量級(jí)也不大,一個(gè)公司最多 也就10萬(wàn)
- 這種情況,數(shù)組區(qū)間范圍是固定的,而且基數(shù)不大最理想的排序算法是計(jì)數(shù)排序
另類用法:旋轉(zhuǎn)數(shù)組中的最小數(shù)字
- 題目:將數(shù)組最開始的若干個(gè)元素搬到數(shù)組的末尾,我們稱為數(shù)組的旋轉(zhuǎn)。輸入一個(gè)遞增數(shù)組的旋轉(zhuǎn),輸出旋轉(zhuǎn)數(shù)組的最小元素,例如數(shù)組{3,4,1,5,1,2}是{1,2,3,4,5}的一個(gè)旋轉(zhuǎn),明顯最小值是1,
分析
-
直觀來(lái)看找最小值一次遍歷就能搞定,時(shí)間復(fù)雜度O(n),但是這個(gè)并沒(méi)有利用這個(gè)數(shù)組的特性,已排序,旋轉(zhuǎn)后兩部分有序肯定有更優(yōu)解
-
旋轉(zhuǎn)后,兩部分?jǐn)?shù)組都有序,并且遞增,必然有序部分后面大于前面
-
然后分界處必然是最小值的特點(diǎn)
-
由上部分分析我們自然想到二分查找尋找最小值。
-
流程如下:
- 定義指針min,max分別指向數(shù)組兩端,按題意,第一個(gè)元素應(yīng)該大于等于 最后一個(gè)元素,因?yàn)樾D(zhuǎn)過(guò)。
- 接著找中間元素mid =(max+ min)/2, 如果中間元素大于min,則min到mid之間處于遞增,則最小值必然在中間元素后面
- 此時(shí)我們將min指針移動(dòng)到mid位置
- 同樣如果中間元素mid 小于min,則表示最小值在mid或者mid的左邊,
- 此時(shí)我們將max指針移動(dòng)到mid位置
- 依次對(duì)min,max之間的數(shù)組部分進(jìn)行如上流程,直到 max - min = 1 為止,此時(shí)最大,最小是相鄰,則找出最小值
-
如下實(shí)際案例{3,4,5,1,2},
- min指針指向第0個(gè)元素 3 ,max指向最后一個(gè)2,中間元素5
- 5 > 3,min移動(dòng)到mid位置,也就是min指向5
- 再次,中間元素變?yōu)?,1<5,此時(shí),最小值在min右邊
- 將max移動(dòng)到mid位置,也就是max指向1 ,
- 此時(shí)max - min = 1,得到最小值max位置。
代碼實(shí)現(xiàn)
/*** @author liaojiamin* @Date:Created in 11:39 2021/3/16*/ public class FindRotateMin {public static int findMin(int[] array){if(array == null || array.length <= 0){return -1;}if(array.length == 1){return array[0];}if(array.length == 2){return array[0]> array[1] ? array[0] : array[1];}int index1 = 0;int index2 = array.length -1;int indexMin = index1;while (array[index1] >= array[index2]){if(index2 - index1 == 1){indexMin = index2;break;}indexMin = (index2 + index1)/2;if(array[indexMin] >= array[index1]){index1 = indexMin;}else if(array[indexMin] <= array[index1]){index2 = indexMin;}}return indexMin;}public static void main(String[] args) {int[] array = {3,4,5,0,1,2};System.out.println(array[findMin(array)]);} }- 問(wèn)題:上述代碼中我們每次判斷都會(huì)有等于的情況,當(dāng)index1, index2,兩個(gè)相同的時(shí)候,并且他們中介的數(shù)字indexMin也相同,這個(gè)時(shí)候,我們符合第一個(gè)判斷,將indexMin賦值給了index1,此時(shí)默認(rèn)最小數(shù)字在后面,其實(shí)不一定對(duì),如下反例
- 數(shù)組{1,0,1,1,1} 和數(shù)組{1,1,1,0,1} 都可以看成遞增排序{0,1,1,1,1}的旋轉(zhuǎn),但是下圖中最小值分別在左邊和右邊:
- 如上情況,首尾數(shù)字,中介位置數(shù)字都是1 ,但是卻有兩種不同的最小值位置,因此這種特殊情況:當(dāng)兩個(gè)指針數(shù)字以及中間數(shù)字都一樣的時(shí)候,無(wú)法判斷最小值的位置,我們不得不采取遍歷的方式。
- 修改代碼如下
測(cè)試用例
- 輸入旋轉(zhuǎn)數(shù)組,數(shù)組中沒(méi)有重復(fù)數(shù)字
- 邊界值測(cè)試,只有一個(gè),兩個(gè)數(shù)字的數(shù)組
- 輸入特殊null值
- 輸入重復(fù)數(shù)字的數(shù)組
上一篇:數(shù)據(jù)結(jié)構(gòu)與算法–利用棧實(shí)現(xiàn)隊(duì)列
下一篇:數(shù)據(jù)結(jié)構(gòu)與算法–再談遞歸與循環(huán)(斐波那契數(shù)列)
總結(jié)
以上是生活随笔為你收集整理的数据结构与算法--查找与排序另类用法-旋转数组中的最小数字的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ipad电池健康度怎么看 ipad怎么看
- 下一篇: 数据结构与算法--再谈递归与循环(斐波那