數字之魅:尋找陣列中的最大值和最小值
陣列是最簡單的一種資料結構。我們經常碰到的一個基本問題,就是尋找整個陣列中最大的數,或者最小的數。這時,我們都會掃描一遍陣列,把最大(最小)的數找出來。如果我們需要同時找出最大和最小的數呢?
對於一個由N個整陣列成的陣列,需要比較多少次才能把最大和最小的數找出來呢?
這個題目比價簡單,主要方案如下:
方案一:分別求最大和最小值。這是一種比較常規的解法。可以分別求出陣列的最大值和最小值,這樣,我們可以採用最基本的冒泡思想遍歷兩次(2N)就能求解。
方案二:分組求解。由於前面的需要遍歷2N次。這裡為了使其遍歷的次數減少,我們可以採用分組。
(1) 按順序將陣列中相鄰的兩個數分在同一組,邏輯上分組,實際什麼都不用做;
(2) 比較同一組的兩個數,將大的數放在偶數位上,小的放在奇數位上;
(3) 最後,從偶數位上求最大值,奇數位上求最小值即可。
這樣一共需要比較1.5N次。這種辦法雖然比較次數變少了,但卻破壞了原陣列,因為我們交換了陣列資料的位置。
方案三:改進的分組。此種方法可以避免破壞原資料的順序。
(1) 用兩個變數max和min分別儲存當前的最大值和最小值。
(2) 同一組的兩個數比較完之後,不再調整順序,將其中較大的與當前max比較,較小的與min比較;
(3) 如此反覆,直到遍歷完整個陣列。
整個過程比較次數也為1.5N次,但是沒有對原資料進行更改,如果資料是在只讀儲存區,那麼該方法就能派上用場了。
方案四:分治策略。該方法用到歸併排序中的merge()函式,雖然方法不一樣,但是可惜的比較的次數還是沒有減少,仍然為1.5N次。在求解的過程中分別求出前後N/2個數的min和max,然後,取較小的min,較大的max即可。
這裡主要是提醒一下經常用的兩種思路:快排你的partion()和歸併裡的merge(),這兩個函式的解決問題的思路十分常用。通常在解決問題的時候,要想到他們,是一種解決的思路。
擴充套件問題
如果需要找出N個數中的第二大數,需要比較多少次呢?是否可以使用類似的分治思想來降低比較的次數呢?
思路一:
用兩個變數分別存最大值max1和次大值max2,遍歷陣列:
初始化:max1=arr[0],max2=0;
先與max2比較,如果比max2大再和max1比較;
如果arr[i] >max1,則更新max=arr[i],max2=max1;
否則如果arr[i] > max2 && arr[i]< max1,則更新max2=arr[i];
否則,不進行更新操作。
這個方法最多的比較次數為2*N次,最大的值在最後面;最小N次第一個和第二個恰好就是最大和第二大的數。
思路二:快速選擇演算法的思想。
對於一個由N個整陣列成的陣列,需要比較多少次才能把最大和最小的數找出來呢?
這個題目比價簡單,主要方案如下:
方案一:分別求最大和最小值。這是一種比較常規的解法。可以分別求出陣列的最大值和最小值,這樣,我們可以採用最基本的冒泡思想遍歷兩次(2N)就能求解。
方案二:分組求解。由於前面的需要遍歷2N次。這裡為了使其遍歷的次數減少,我們可以採用分組。
(1) 按順序將陣列中相鄰的兩個數分在同一組,邏輯上分組,實際什麼都不用做;
(2) 比較同一組的兩個數,將大的數放在偶數位上,小的放在奇數位上;
(3) 最後,從偶數位上求最大值,奇數位上求最小值即可。
這樣一共需要比較1.5N次。這種辦法雖然比較次數變少了,但卻破壞了原陣列,因為我們交換了陣列資料的位置。
方案三:改進的分組。此種方法可以避免破壞原資料的順序。
(1) 用兩個變數max和min分別儲存當前的最大值和最小值。
(2) 同一組的兩個數比較完之後,不再調整順序,將其中較大的與當前max比較,較小的與min比較;
(3) 如此反覆,直到遍歷完整個陣列。
整個過程比較次數也為1.5N次,但是沒有對原資料進行更改,如果資料是在只讀儲存區,那麼該方法就能派上用場了。
方案四:分治策略。該方法用到歸併排序中的merge()函式,雖然方法不一樣,但是可惜的比較的次數還是沒有減少,仍然為1.5N次。在求解的過程中分別求出前後N/2個數的min和max,然後,取較小的min,較大的max即可。
這裡主要是提醒一下經常用的兩種思路:快排你的partion()和歸併裡的merge(),這兩個函式的解決問題的思路十分常用。通常在解決問題的時候,要想到他們,是一種解決的思路。
擴充套件問題
如果需要找出N個數中的第二大數,需要比較多少次呢?是否可以使用類似的分治思想來降低比較的次數呢?
思路一:
用兩個變數分別存最大值max1和次大值max2,遍歷陣列:
初始化:max1=arr[0],max2=0;
先與max2比較,如果比max2大再和max1比較;
如果arr[i] >max1,則更新max=arr[i],max2=max1;
否則如果arr[i] > max2 && arr[i]< max1,則更新max2=arr[i];
否則,不進行更新操作。
這個方法最多的比較次數為2*N次,最大的值在最後面;最小N次第一個和第二個恰好就是最大和第二大的數。
思路二:快速選擇演算法的思想。
先尋找出第k大的整數,然後再通過兩次遍歷前k大的數字找出第二大的數字,因為找出的前k個元素是不保證排序的。比較的次數為:找出前K個元素次時:最好k次,最壞N次。然後在前k個元素中找出第K個元素:比較的次數:k+k-1次。所以比較的次數為:最好3k-1次,最壞:N+2k-1次。
相關文章
- 尋找陣列中的最大值和最小值O(1.5*N)陣列
- JavaScript陣列中的最大值和最小值JavaScript陣列
- 153. 尋找旋轉排序陣列中的最小值(中)排序陣列
- 153. 尋找旋轉排序陣列中的最小值排序陣列
- JavaScript 陣列最大值和最小值JavaScript陣列
- LeetCode-153-尋找旋轉排序陣列中的最小值LeetCode排序陣列
- 【LeetCode】153. 尋找旋轉排序陣列中的最小值LeetCode排序陣列
- JavaScript陣列最大值、最小值和平均數JavaScript陣列
- JavaScript獲取陣列最大值和最小值JavaScript陣列
- 尋找兩個有序陣列的中位數陣列
- 尋找兩個正序陣列中的中位數陣列
- GO實現:leetcode之尋找兩個正序陣列的中位數GoLeetCode陣列
- 【Java】尋找陣列中“主要元素”Java陣列
- 尋找陣列中第K大的元素陣列
- LeetCode--尋找兩個有序陣列的中位數(05)LeetCode陣列
- 4. 尋找兩個正序陣列的中位數陣列
- 尋找陣列的中心索引陣列索引
- 求陣列之和,最小值,最大值,平均值陣列
- LeetCode第4題:尋找兩個有序陣列的中位數LeetCode陣列
- 尋找陣列中和為定值的兩個數陣列
- js獲取數字陣列最大值的幾種方式JS陣列
- 找一個陣列中特別的數陣列
- [LeetCode 刷題] 4. 尋找兩個有序陣列的中位數 (Hard)LeetCode陣列
- 【LeetCode Hot 100】4. 尋找兩個正序陣列的中位數LeetCode陣列
- 尋找兩個正序陣列的中位數問題,方法一:合併陣列檢索法陣列
- [劍之offer] 03 陣列中重複的數字陣列
- 修改陣列【並查集維護集合的最大值、連續數字的最大值】陣列並查集
- LeetCode解題(C++)-4. 尋找兩個有序陣列的中位數LeetCodeC++陣列
- lgP5788 陣列中尋找右側第一個大於它的數陣列
- 力扣演算法題:尋找兩個正序陣列的中位數力扣演算法陣列
- 陣列中重複的數字陣列
- LeetCode:尋找丟失的數字LeetCode
- LeetCodeHot100 二分查詢 35. 搜尋插入位置 74. 搜尋二維矩陣 34. 在排序陣列中查詢元素的第一個和最後一個位置 33. 搜尋旋轉排序陣列 153. 尋找旋轉排序陣列中的最小值LeetCode矩陣排序陣列
- 1452: 陣列最小值陣列
- JavaScript可以設定最大值和最小值的隨機數JavaScript隨機
- LeetCode題集-4 - 尋找兩個有序陣列的中位數,圖文並茂,六種解法,萬字講解LeetCode陣列
- 2419 求最大值和最小值
- leetcode 4. Median of Two Sorted Arrays 尋找兩個正序陣列的中位數(困難)LeetCode陣列
- JAVA 求出一個一維int型陣列的元素最大值、最小值、平均值、和所有元素之和Java陣列