輸入n個數,最壞情況下用 n + logn
這個題我一開始是遞迴 從底層出發 比到頂層 顯然時間複雜度不允許
後來想了一種n時間複雜度的
開兩個數用來維護最大值和最小值就可以了,什麼意思呢
比如 1 3 6 2 8 4 0 0 8是我們要求的陣列
int last = Integer.Min_Value;
int cur = Integer.Min_Value;
分別代表了上一個最大值和當前最大值
我們走到a[0] cur = 1
到a[1] cur=3 last = 1
繼續走 cur=6 last=3
...
維護到最後,這兩個數就是最大值和次大值了
但是既然要求的是n+logN,那就用競賽的思想(網上看的)
分析:
例如這n(n=8)個數分別是:8 7 9 2 3 6 10 12
第一輪比賽:(8,7) (9,2) (3,6) (10,12) 比較了4次
得到第一輪的入選者:8 9 6 12
第二輪比賽:(8 9) (6 12) 比較了2次
得到第二輪的入選者:9 12
第三輪比賽:(9 12) 比較了1次
得到第三輪的入選者:12 12既是比賽的冠軍
以上得到冠軍總共比較了7次,即n-1次
只有和冠軍比過的人才有可能是亞軍,這句話就是關鍵。為什麼只有和冠軍比過的人才有可能是亞軍,因為都沒和冠軍必過,證明肯定分組不是和冠軍一個分組的而且別另外的數給虐了。所以我們只需要開一個int變數去維護亞軍就可以了。
顯然第一輪變數 維護的亞軍=10
第二輪是6 所以維護的亞軍還是=10
比到最後 維護的還是10
所以就得出來了(如果有更大的就會更新這個量)
一共7+3=10次
但是在比賽之前你咋知道誰是冠軍?難道你和演員的誕生一樣有黑幕?
所以正確的做法是空間換時間,把每組比賽都存放進不同的陣列中。
之後我們進行比賽得出了12是冠軍,我們就可以通過12在陣列中的定位,找到和他比的人。
比如說
8 7 9 2 3 6 10 12
8 9 6 12
9 12
12
我們可以把10,6,9入我們的新陣列繼續去比(但是注意不能像上面一樣比了),因為資料大的時候,每次和冠軍比的人有很多所以新陣列繼續去按之前的方式一樣比。
就搞定啦!
最後思考一下最壞情況 並引出另一種方法
就是比如9個數 第一次複雜度為n 你找到了最大值
在找的過程中我們把9個數分成了3組 分別求出了最大值 這個時候我們想求次大值 難道就是這3組值中的第2大的值嗎?錯了!這個時候就出現了最壞情況,次大值可能是3組值中第二大的值,但是也完全有可能出現在最大值的那一組中!所以這就是最壞情況的麻煩之處。所以我們在第一次找的過程中,不僅要把9個數分成三組求出最大值,還要求出次大值,那麼這樣就規避了最壞情況。我們第一輪找求出了最大值,我們定位那一組,找到那一組的次大值。再定位次大值的那一組,找到那一組的最大值,再進行比較,就搞定啦!
程式碼就不貼啦!
相關推薦
輸入n個數,最壞情況下用 n + logn
這個題我一開始是遞迴 從底層出發 比到頂層 顯然時間複雜度不允許後來想了一種n時間複雜度的開兩個數用來維護最大值和最小值就可以了,什麼意思呢比如 1 3 6 2 8 4 0 0 8是我們要求的陣列int last = Integer.Min_Value;int cur = I
給定陣列a[0:n-1]試設計一個演算法,在最壞情況下用[3n/2 -2 ] 次比較找出a[0:n-1]中元素的最大值和最小值;教材2-15
給定陣列a[0:n-1]試設計一個演算法,在最壞情況下用[3n/2 -2 ] 次比較找出a[0:n-1]中元素的最大值和最小值; 解:要求對於陣列用小於【3n/2-2】的比較次數找到兩個最值 可以用陣列第一個元素來初始化max,min 然後遍歷陣列,分別和max,min比較,一遍就可以找
合併兩個長度分別為m和n的有序表,最壞情況下需要比較m+n-1次
最壞的情況就是交叉的情況: 比如 1 3 52 4 6 設上鍊指針p,下鏈q,每次比較後較小節點依次作為“合併後連結串列的節點”,同時較小鏈指標後移。某鏈指空後不再比較。則樓上所給的第一個例
[百度面試題]100層樓,球可能會在某一層樓摔壞,問用2個球,最壞情況下幾次測試可以找出該樓層
該題還可以擴充套件,比如說給更多的球,如3個球,多少次測試可以找出樓層。 分析如下: 用動態規劃解這個問題 設f(a, b)為a個球做b次測試可以測試到的樓層數,可以確定的樓層數即為f(a, b) + 1,因為第1層不需測試,需要測試的樓層號僅僅為[2, f(a, b) +
100層樓有一個雞蛋,如果確定剛好摔碎的那個樓層,最壞情況下最少需要摔多少次?
分析:這道題我們應反過來考慮,就是用a塊石頭扔b次至多一定可分辨層數X(a,b)。先從最簡裝的一塊石頭考慮,很顯然,X(1,1) = 1X(1,2) = 2X(1,3) = 3.X(1,i) = i再考慮二塊石頭,顯而易見X(2,1) = 1對於X(2,2),我們可這樣考慮,當我們扔第一次後,有兩種可能:破和
夜深人靜寫演算法———線性時間選擇(分治,最壞情況處理)
一: 線性時間選擇中,最壞情況下時間複雜度為O(n^2) , 但如果線上性時間內找到一個劃分基準,使得按照這個基準所劃分的兩個子陣列的長度至少為原陣列的k倍( 0<k<1)。 二: (1) 將n個輸入的元素分成 (n-4)/5組,每一組都是5個元素,可
演算法設計:有n個數,範圍是從1到n,且只有唯一的兩個數相同,如何最快的求相同的這個數值?
為了方便問題描述,假設n = 10,即陣列a[10]裡有10個數,範圍是從1到10,且裡面只有兩個數的值是相同的。如何求這個相同的數值。 常規思路: 1,先氣泡排序,然後用while迴圈找出這個相同的數值 2,直接用冒泡的思路,i從0到n-2,j = i+1,依次比,找出相
排序演算法--時間複雜度(平均時間,最壞情況)、空間複雜度
1、時間複雜度:一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式f(n),演算法的時間量度記作:
shell指令碼之任意輸入n個數,判斷最大值,最小值,總和
#!/bin/bash ##任意輸入n個數,判斷最大值,最小值,總和 sum=0 n=0 read -p "please input the count of number:" count #max
輸入兩個數,輸出其最大公約數和最小公倍數,並輸出所有的公約數
輸入兩個數,求其最大公約數和最小公倍數,並輸出所有的公約數 以下分別用三種方法求最大公約數,詳細程式碼如下: #include <iostream> using namespace std; //求最大公約數:求差法 void div1(int m,int n){ i
寫一個函式,輸入一個數,隨機生成N條郵箱
寫一個函式,這個函式的功能是,傳入一個數字,產生N條郵箱,產生的手機號不能重複。郵箱前面的長度是6 - 12之間,產生的郵箱必須包含大寫字母、小寫字母、數字和特殊字元 import random
輸入三個數,輸出其最大值
#include<stdio.h> int main() { int t,a,b,c; scanf("%d%d%d",&a,&b,&c); if(a>b) if(a>c) t=a; else t=c; el
C語言 習題 輸入n個數,輸出不重複的數及它們的和
難住本小白的一道c語言題目,搞了兩天才出來,不多比比,直接上題 題目:輸入n個整數,輸出不重複整數及它們的和。 //講真,當時那道題,讀了兩遍愣是沒懂······ 此題筆者認為有兩個難點, 1.“如何輸入n個整數”,當按下回車鍵時結束輸入,其中n是不定的,(不能要求先輸入n的值,那樣難度直接
先宣告一個數組int[] arr,初始化長度為5 從鍵盤輸入數字存到陣列中,每輸入一個數字,詢問是否繼續(Y/N),如果是Y,就繼續,直到輸入N結束輸入 如果陣列存滿了,要實現陣列擴容的效果(提示,新
package com.atguigu.java; import java.util.Scanner; public class TextJava{ public static void main(String[] args){ Scanner input =
(03)從鍵盤輸入一個數,求出這個數的階乘,即 n!。
題目描述 從鍵盤輸入一個數,求出這個數的階乘,即 n!。 演算法思想 首先要清楚階乘定義,所謂 n 的階乘,就是從 1 開始乘以比前一個數大 1 的數,一直乘到 n,用公式表示就是:1×2×3×4×…×(n-2)×(n-1)×n=n! 具體
輸入n個數,判斷正數.負數.0的個數
#include<stdio.h> int main() { float p[100]; int i, m, n, k, l; m = 0; k = 0; l = 0; scan
C++ ,輸入5個數,讓最大值和第一 個數交換,讓最小值和最後一個數交換
#include "iostream" using namespace std; int main() { const int n=6; //靈活定義陣列的大小 int
從鍵盤上輸入三個數,編寫一個max函式,可以輸出三個數中最大的數字
int max(int a,int b,int c ); int main(int argc, const char * argv[]) { int a,b,c; scanf("%d",&a); scanf("%d",&b);
給出n個數,找出這n個數的最大值,最小值,以及這些數字的和
<div class="sec_header">問題描述</div><div class="sec_cont"><p>給出n個數,找出這n個數的最大值,最小值,和。</p></div><div c
劍指offer之找出陣列中最小的n個數,之優先佇列
這道題最簡單的就是排序,時間複雜度O(nlogn)。不再講述。這裡可以使用優先佇列,時間複雜度O(nlogk)。注意檢驗k的合法性,不然初始化佇列時會報錯。import java.util.ArrayL