當前位置:首頁 » 操作系統 » 面試演算法問題

面試演算法問題

發布時間: 2023-03-01 09:51:57

1. 面試難點!常用演算法技巧之「滑動窗口」

滑動窗口,顧名思義,就是有一個大小可變的窗口,左右兩端方向一致的向前滑動(右端固定,左端滑動;左端固定,右端滑動)。

可以想像成隊列,一端在push元素,另一端在pop元素,如下所示:

假設有數組[a b c d e f g h]
一個大小為3的滑動窗口在其上滑動,則有:

1、單層循環

2、雙層循環

模板只是一個解題思路,具體的題目可能需要具體分析,但是大體框架是不變的。
記住: 多刷題,多總結,是王道

1、最長不含重復字元的子字元串

2、絕對差不超過限制的最長連續子數組

3、無重復字元的最長子串

4、替換後的最長重復字元

滑動窗口演算法就是用以解決數組/字元串的子元素問題
滑動窗口演算法可以將嵌套的for循環問題,轉換為單循環問題,降低時間復雜度

生命不止堅毅魚奮斗,有夢想才是有意義的追求
給大家推薦一個免費的學習交流群:
最後,祝大家早日學有所成,拿到滿意offer,快速升職加薪,走上人生巔峰。
java開發交流君樣:756584822

2. 阿裡面試演算法題合集一

0,1,,n-1這n個數字排成一個圓圈,從數字0開始,每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後一個數字。

例如,0、1、2、3、4這5個數字組成一個圓圈,從數字0開始每次刪除第3個數字,則刪除的前4個數字依次是2、0、4、1,因此最後剩下的數字是3。

示例 1:

輸入: n = 5, m = 3
輸出: 3
示例 2:

輸入: n = 10, m = 17
輸出: 2

請實現一個函數,輸入一個整數,輸出該數二進製表示中 1 的個數。例如,把 9 表示成二進制是 1001,有 2 位是 1。因此,如果輸入 9,則該函數輸出 2。

示例 1:

輸入:
輸出:3
解釋:輸入的二進制串 中,共有三位為 '1'。

數字以0123456789101112131415…的格式序列化到一個字元序列中。在這個序列中,第5位(從下標0開始計數)是5,第13位是1,第19位是4,等等。

請寫一個函數,求任意第n位對應的數字。

示例 1:

輸入:n = 3
輸出:3
示例 2:

輸入:n = 11
輸出:0

注意這里必須是long 類型

輸入一個非負整數數組,把數組里所有數字拼接起來排成一個數,列印能拼接出的所有數字中最小的一個。

示例 1:

輸入: [10,2]
輸出: "102"
示例 2:

輸入: [3,30,34,5,9]
輸出: "3033459"

老師想給孩子們分發糖果,有 N 個孩子站成了一條直線,老師會根據每個孩子的表現,預先給他們評分。

你需要按照以下要求,幫助老師給這些孩子分發糖果:

每個孩子至少分配到 1 個糖果。
相鄰的孩子中,評分高的孩子必須獲得更多的糖果。
那麼這樣下來,老師至少需要准備多少顆糖果呢?

示例 1:

輸入: [1,0,2]
輸出: 5
解釋: 你可以分別給這三個孩子分發 2、1、2 顆糖果。
示例 2:

輸入: [1,2,2]
輸出: 4
解釋: 你可以分別給這三個孩子分發 1、2、1 顆糖果。
第三個孩子只得到 1 顆糖果,這已滿足上述兩個條件。

在一條環路上有 N 個加油站,其中第 i 個加油站有汽油 gas[i] 升。

你有一輛油箱容量無限的的汽車,從第 i 個加油站開往第 i+1 個加油站需要消耗汽油 cost[i] 升。你從其中的一個加油站出發,開始時油箱為空。

如果你可以繞環路行駛一周,則返回出發時加油站的編號,否則返回 -1。

說明:

如果題目有解,該答案即為唯一答案。
輸入數組均為非空數組,且長度相同。
輸入數組中的元素均為非負數。
示例 1:

輸入:
gas = [1,2,3,4,5]
cost = [3,4,5,1,2]

輸出: 3

貪心的思路是,只要總和大於0 就可以繞一圈,
開始位置的貪心思路是,如果從剛開始sum小於0,一定不是從之前開始,而是從當前下一個位置,sum = 0 清空

給定一個非負整數數組,你最初位於數組的第一個位置。

數組中的每個元素代表你在該位置可以跳躍的最大長度。

你的目標是使用最少的跳躍次數到達數組的最後一個位置。

示例:

輸入: [2,3,1,1,4]
輸出: 2
解釋: 跳到最後一個位置的最小跳躍數是 2。
從下標為 0 跳到下標為 1 的位置,跳 1 步,然後跳 3 步到達數組的最後一個位置。

給定一個非負整數數組,你最初位於數組的第一個位置。

數組中的每個元素代表你在該位置可以跳躍的最大長度。

判斷你是否能夠到達最後一個位置。

示例 1:

輸入: [2,3,1,1,4]
輸出: true
解釋: 我們可以先跳 1 步,從位置 0 到達 位置 1, 然後再從位置 1 跳 3 步到達最後一個位置。

一條包含字母 A-Z 的消息通過以下方式進行了編碼:

'A' -> 1
'B' -> 2
...
'Z' -> 26
給定一個只包含數字的非空字元串,請計算解碼方法的總數。

示例 1:

輸入: "12"
輸出: 2
解釋: 它可以解碼為 "AB"(1 2)或者 "L"(12)。

這里一定注意 第一個數為0 的情況,s.charAt(0) == '0' 第一個為0 要直接返回0 才行

給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。

如果你最多隻允許完成一筆交易(即買入和賣出一支股票一次),設計一個演算法來計算你所能獲取的最大利潤。

注意:你不能在買入股票前賣出股票。

示例 1:

輸入: [7,1,5,3,6,4]
輸出: 5
解釋: 在第 2 天(股票價格 = 1)的時候買入,在第 5 天(股票價格 = 6)的時候賣出,最大利潤 = 6-1 = 5 。
注意利潤不能是 7-1 = 6, 因為賣出價格需要大於買入價格;同時,你不能在買入前賣出股票。

給定三個字元串 s1, s2, s3, 驗證 s3 是否是由 s1 和 s2 交錯組成的。

示例 1:

輸入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
輸出: true

給你一個字元串 s 和一個字元規律 p,請你來實現一個支持 '.' 和 '*' 的正則表達式匹配。

'.' 匹配任意單個字元
'*' 匹配零個或多個前面的那一個元素
所謂匹配,是要涵蓋 整個 字元串 s的,而不是部分字元串。

說明:

s 可能為空,且只包含從 a-z 的小寫字母。
p 可能為空,且只包含從 a-z 的小寫字母,以及字元 . 和 *。
示例 1:

輸入:
s = "aa"
p = "a"
輸出: false
解釋: "a" 無法匹配 "aa" 整個字元串。

給定一個整數矩陣,找出最長遞增路徑的長度。

對於每個單元格,你可以往上,下,左,右四個方向移動。 你不能在對角線方向上移動或移動到邊界外(即不允許環繞)。

示例 1:

輸入: nums =
[
[9,9,4],
[6,6,8],
[2,1,1]
]
輸出: 4
解釋: 最長遞增路徑為 [1, 2, 6, 9]。

使用帶記憶的可以避免超時

使用動態規劃解題

給出一個由無重復的正整數組成的集合,找出其中最大的整除子集,子集中任意一對 (Si,Sj) 都要滿足:Si % Sj = 0 或 Sj % Si = 0。

如果有多個目標子集,返回其中任何一個均可。

示例 1:

輸入: [1,2,3]
輸出: [1,2] (當然, [1,3] 也正確)

給定一些標記了寬度和高度的信封,寬度和高度以整數對形式 (w, h) 出現。當另一個信封的寬度和高度都比這個信封大的時候,這個信封就可以放進另一個信封里,如同俄羅斯套娃一樣。

請計算最多能有多少個信封能組成一組「俄羅斯套娃」信封(即可以把一個信封放到另一個信封裡面)。

說明:
不允許旋轉信封。

示例:

輸入: envelopes = [[5,4],[6,4],[6,7],[2,3]]
輸出: 3
解釋: 最多信封的個數為 3, 組合為: [2,3] => [5,4] => [6,7]。

標準的動態規劃

一隻青蛙想要過河。 假定河流被等分為 x 個單元格,並且在每一個單元格內都有可能放有一石子(也有可能沒有)。 青蛙可以跳上石頭,但是不可以跳入水中。

給定石子的位置列表(用單元格序號升序表示), 請判定青蛙能否成功過河(即能否在最後一步跳至最後一個石子上)。 開始時, 青蛙默認已站在第一個石子上,並可以假定它第一步只能跳躍一個單位(即只能從單元格1跳至單元格2)。

如果青蛙上一步跳躍了 k 個單位,那麼它接下來的跳躍距離只能選擇為 k - 1、k 或 k + 1個單位。 另請注意,青蛙只能向前方(終點的方向)跳躍。

請注意:

石子的數量 ≥ 2 且 < 1100;
每一個石子的位置序號都是一個非負整數,且其 < 231;
第一個石子的位置永遠是0。
示例 1:

[0,1,3,5,6,8,12,17]

true

使用數組+ 鏈表枚舉所有的可能

給你兩個單詞 word1 和 word2,請你計算出將 word1 轉換成 word2 所使用的最少操作數 。

你可以對一個單詞進行如下三種操作:

插入一個字元
刪除一個字元
替換一個字元

示例 1:

輸入:word1 = "horse", word2 = "ros"
輸出:3
解釋:
horse -> rorse (將 'h' 替換為 'r')
rorse -> rose (刪除 'r')
rose -> ros (刪除 'e')

給定不同面額的硬幣 coins 和一個總金額 amount。編寫一個函數來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1。

示例 1:

輸入: coins = [1, 2, 5], amount = 11
輸出: 3
解釋: 11 = 5 + 5 + 1
示例 2:

輸入: coins = [2], amount = 3
輸出: -1

給定一個字元串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為 1000。

示例 1:

輸入: "babad"
輸出: "bab"
注意: "aba" 也是一個有效答案。

給定一個字元串 S 和一個字元串 T,計算在 S 的子序列中 T 出現的個數。

一個字元串的一個子序列是指,通過刪除一些(也可以不刪除)字元且不幹擾剩餘字元相對位置所組成的新字元串。(例如,"ACE" 是 "ABCDE" 的一個子序列,而 "AEC" 不是)

題目數據保證答案符合 32 位帶符號整數范圍。

示例 1:

輸入:S = "rabbbit", T = "rabbit"
輸出:3

給定一個無序的整數數組,找到其中最長上升子序列的長度。

示例:

輸入: [10,9,2,5,3,7,101,18]
輸出: 4

使用二分查詢

在一個由 0 和 1 組成的二維矩陣內,找到只包含 1 的最大正方形,並返回其面積。

示例:

輸入:

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0

輸出: 4

給定正整數 n,找到若干個完全平方數(比如 1, 4, 9, 16, ...)使得它們的和等於 n。你需要讓組成和的完全平方數的個數最少。

示例 1:

輸入: n = 12
輸出: 3
解釋: 12 = 4 + 4 + 4.

你是一個專業的小偷,計劃偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。

給定一個代表每個房屋存放金額的非負整數數組,計算你 不觸動警報裝置的情況下 ,一夜之內能夠偷竊到的最高金額。

示例 1:

輸入:[1,2,3,1]
輸出:4

你是一個專業的小偷,計劃偷竊沿街的房屋,每間房內都藏有一定的現金。這個地方所有的房屋都圍成一圈,這意味著第一個房屋和最後一個房屋是緊挨著的。同時,相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。

給定一個代表每個房屋存放金額的非負整數數組,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。

示例 1:

輸入: [2,3,2]
輸出: 3

思路是忽略第一個求一個結果,忽略最後一個求一個結果,只要一個時一個結果

// 可以使用rangeCopy 將其放入一個函數中求解

給定一個三角形,找出自頂向下的最小路徑和。每一步只能移動到下一行中相鄰的結點上。

相鄰的結點 在這里指的是 下標 與 上一層結點下標 相同或者等於 上一層結點下標 + 1 的兩個結點。

例如,給定三角形:

[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自頂向下的最小路徑和為 11(即,2 + 3 + 5 + 1 = 11)。

給定一個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。

說明:每次只能向下或者向右移動一步。

示例:

輸入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
輸出: 7

一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記為「Start」 )。

機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為「Finish」)。

現在考慮網格中有障礙物。那麼從左上角到右下角將會有多少條不同的路徑?

示例 1:

輸入:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
輸出: 2

一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記為「Start」 )。

機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為「Finish」)。

問總共有多少條不同的路徑?

假設你正在爬樓梯。需要 n 階你才能到達樓頂。

每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂呢?

注意:給定 n 是一個正整數。

示例 1:

輸入: 2
輸出: 2

3. 經典C語言面試演算法題

經典C語言面試演算法題

1.寫一個函數,它的原形是int continumax(char *outputstr,char *intputstr)

功能:

在字元串中找出連續最長的數字串,並把這個串的長度返回,並把這個最長數字串付給其中一個函數參數outputstr所指內存。例如:"abcd12345ed125ss123456789"的首地址傳給intputstr後,函數將返回

9,outputstr所指的值為123456789。

#include

#include

#include

int FindMax_NumStr(char *outputstr,char *inputstr)

{

char *in = inputstr,*out = outputstr,*temp;

char *final;

int count = 0;

int maxlen = 0;

int i;

while(*in!='')

{

if(*in > 47 && *in < 58)

{

for(temp = in;*in> 47 && *in <58;in++)

count++;

}

else

in++;

if(maxlen < count)

{

maxlen = count;

count = 0;

final = temp;

}

}

for(i =0;i

{

*out = *final;

out++;

final++;

}

*out = '';

return maxlen;

}

void main(void)

{

char input[]="abc123def123456eec123456789dd";

char output[50] = {0};

int maxlen;

maxlen = FindMax_NumStr(output,input);

printf("the str %s ",output);

printf("the maxlen is %d ",maxlen);

}

2.求1000!的未尾有幾個0;

求出1->1000里,能被5整除的數的個數n1,能被25整除的數的個數n2,能被125整除的'數的個數n3,能被625整除的數的個數n4.1000!末尾的零的個數=n1+n2+n3+n4;

只要是末尾是5的數它乘以一個偶數就會出現一個0,而末尾是0的數乘以任何數也都會出現0

而末尾是0的如果是一個0肯定能被5整除,兩個0肯定能被25整數,以此類推3個0就能被5的三次方整除,也就是125

1000!就是1-1000數的相乘,能被5整除的所有數分別乘以一個偶數就會出現這些個的0,而例如100,既能被5整除,也能被25整除,所以就是兩個0

1000,既能被5,25,也能被125整除,所以算三個0

例如是10!=1*2*3*4*5*6*7*8*9*10,裡面有兩個數能被5整除,就是10和5,而

5隨便乘以一個偶數就出現一個0,而10乘以其它數也會出現一個0,所以10!會有兩個0

#include

#define NUM 1000

int find5(int num)

{

int ret = 0;

while(num%5==0)

{

num/=5;

ret++;

}

return ret;

}

int main(void)

{

int result = 0;

int i;

for(i=5;i<=NUM;i+=5)

result +=find5(i);

printf("the total zero number is %d ",result);

return 0;

}

3。編寫一個 C 函數,該函數在一個字元串中找到可能的最長的子字元串,且該字元串是由同一字元組成的。

char * search(char *cpSource, char ch)

{

char *cpTemp=NULL, *cpDest=NULL;

int iTemp, iCount=0;

while(*cpSource)

{

if(*cpSource == ch)

{

iTemp = 0;

cpTemp = cpSource;

while(*cpSource == ch)

++iTemp, ++cpSource;

if(iTemp > iCount)

iCount = iTemp, cpDest = cpTemp;

if(!*cpSource)

break;

}

++cpSource;

}

return cpDest;

}

;

4. 大公司筆試面試有哪些經典演算法題目

1、二維數組中的查找

具體例題:如果一個數字序列逆置之後跟原序列是一樣的就稱這樣的數字序列為迴文序列。例如:{1, 2, 1}, {15, 78, 78, 15} , {112} 是迴文序列, {1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是迴文序列。現在給出一個數字序列,允許使用一種轉換操作:選擇任意兩個相鄰的數,然後從序列移除這兩個數,並用這兩個數字的和插入到這兩個數之前的位置(只插入一個和)。現在對於所給序列要求出最少需要多少次操作可以將其變成迴文序列?



5. 面試演算法題

定義一個函數實現數據類型的轉換

第一個元素是數據標識,第二個元素的數值必須大於等於50才返回,不夠50往後累加,加到最後如果不夠50也直接返回,因為沒有可加的數據了

例子1:

a = [[1,3],[2,51],[3,49],[4,42],[5,42]] #入參

a1 = [[2,54],[4,91],[5,42]] #返回

例子2:

b = [[1,50],[2,5],[3,10],[4,42],[5,42],[6,10]] #入參

b1 = [[1,50],[4,57],[6,52]] #返回

a = [[1, 3], [2, 51], [3, 49], [4, 42], [5, 42]]

li = []

n =0

for i, kin a:

    n += k

    if n >=50:

       li.append([i, n])

        n =0

    elif len(a) == i:

li.append([i, k])

    print(li)

一個球從100米高度自由落下,每次落地後反跳回原高度的一半;再落下,求它在第10次落地時,共經過多少米?第10次反彈多高?

def fun(n):

    if n ==1:

        return 100 /2

    else:

        res = fun(n -1) /2

        return res

print(fun(10))

def func(n):

    if n ==1:

        return 100

    else:

        return (fun(n -1) *2) + func(n -1)

print(func(10))

# for 循環實現

def height_100():

# 定義S用來計算總距離

    s =0

    h =100

    for iin range(10):

# 加上本次落地的距離

        s += h

h = h /2

        # 加上反彈的距離

        s += h

print(f'第10次落地的總距離為:{s-h}')

print(f'第10次反彈的高度:{h}')

height_100()

斐波拉契數列

[1,1,2,3,5,8,13,21,34,55]

分析:

月份      數量

1        2隻

2        2隻

3        4隻

4        6隻

5        10隻

6        16隻

def tu_func(n):

    if n ==1 or n ==2:

            return 2

    else:

            return tu_func(n -1) + tu_func(n -2)

print(tu_func(10))

# for 循環實現

def tu_func1(n):

    s = []

    for iin range(1, n +1):

    if i ==1 or i ==2:

        s.append(2)

    else:

            s.append(s[i -2] + s[i -3])

    return s

print(tu_func1(10))

小明有100元錢 打算買100本書,A類書籍5元一本,B類書籍3元一本,C類書籍1元兩本,

    請用程序算出小明一共有多少種買法?

def func3():

    count =0

    for ain range(21):

            for bin range(34):

                    c =100 - a - b

                    if a *5 + b *3 + c *0.5 ==100:

                        count +=1

                        print(a, b, c)

    print(F'一共有{count}種買法')

func3()

6. 如何回答面試演算法問題

給定一個有序數組xxx 中,"有序"是否可以利用?

a: 用幾個簡單的測試用例,檢驗一下
b:暴力解法 通常都是思考的起點.

a: 遍歷常見的演算法思路
b: 遍歷常見的數據結構

c: 空間和時間的交換?
d: 預處理數據 => 排序
e: 在瓶頸處找到答案

a: 極端條件判斷
數組為空? 字元串==null? 數字==0? 指針->null?
b: 變數名等 符合規范
c: 注重模塊化,復用性

演算法在1s之內 可解決的問題:
O(n^2) 的演算法可處理大約10^4級別的數據
O(n) 的演算法可處理大約10^8級別的數據
O(nlogn)的演算法可處理大約10^7級別的數據

7. 面試經典數據結構和演算法匯總

如果說數據結構是骨架,那麼演算法就是靈魂。沒了骨架,靈魂沒有實體寄託;沒了靈魂,骨架也是個空殼。兩者相輔相成,缺一不可,在開發中起到了砥柱中流的作用。

現在我對各種數據結構和演算法做一總結,對比一下它們的效率

1.數據結構篇
1. 如果讓你手寫個棧和隊列,你還會寫嗎?
2. 開發了那麼多項目,你能自己手寫個健壯的鏈表出來嗎?
3. 下次面試若再被問到二叉樹,希望你能對答如流!
4. 面試還在被紅-黑樹虐?看完這篇輕松搞定面試官 !

2.排序演算法篇
1. 幾個經典的基礎排序演算法,你還記得嗎?
2. 手把手教你學會希爾排序,很簡單!
3. 快速排序演算法到底有多快?
4. 五分鍾教你學會歸並排序
5. 簡單說下二叉樹排序
6. 學會堆排序只需要幾分鍾
7. 圖,這個玩意兒竟然還可以用來排序!

掌握了這些經典的數據結構和演算法,面試啥的基本上沒什麼問題了,特別是對於那些應屆生來說。接下來再總結一下不同數據結構和演算法的效率問題,做一下對比,這也是面試官經常問的問題。

數據結構常用操作效率對比:

常用排序演算法效率的對比:

關於經典的數據結構和演算法,就總結到這,本文建議收藏,利用等公交、各種排隊之時提升自己。這世上天才很少,懶蛋卻很多,你若對得起時間,時間便對得起你。

8. java演算法面試題:排序都有哪幾種方法

一、冒泡排序
[java] view plain
package sort.bubble;
import java.util.Random;
/**
* 依次比較相鄰的兩個數,將小數放在前面,大數放在後面
* 冒泡排序,具有穩定性
* 時間復雜度為O(n^2)
* 不及堆排序,快速排序O(nlogn,底數為2)
* @author liangge
*
*/
public class Main {
public static void main(String[] args) {
Random ran = new Random();
int[] sort = new int[10];
for(int i = 0 ; i < 10 ; i++){
sort[i] = ran.nextInt(50);
}
System.out.print("排序前的數組為");
for(int i : sort){
System.out.print(i+" ");
}
buddleSort(sort);
System.out.println();
System.out.print("排序後的數組為");
for(int i : sort){
System.out.print(i+" ");
}
}
/**
* 冒泡排序
* @param sort
*/
private static void buddleSort(int[] sort){
for(int i=1;i<sort.length;i++){
for(int j=0;j<sort.length-i;j++){
if(sort[j]>sort[j+1]){
int temp = sort[j+1];
sort[j+1] = sort[j];
sort[j] = temp;
}
}
}
}
}
二、選擇排序
[java] view plain
package sort.select;
import java.util.Random;
/**
* 選擇排序
* 每一趟從待排序的數據元素中選出最小(或最大)的一個元素,
* 順序放在已排好序的數列的最後,直到全部待排序的數據元素排完。
* 選擇排序是不穩定的排序方法。
* @author liangge
*
*/
public class Main {
public static void main(String[] args) {
Random ran = new Random();
int[] sort = new int[10];
for (int i = 0; i < 10; i++) {
sort[i] = ran.nextInt(50);
}
System.out.print("排序前的數組為");
for (int i : sort) {
System.out.print(i + " ");
}
selectSort(sort);
System.out.println();
System.out.print("排序後的數組為");
for (int i : sort) {
System.out.print(i + " ");
}
}
/**
* 選擇排序
* @param sort
*/
private static void selectSort(int[] sort){
for(int i =0;i<sort.length-1;i++){
for(int j = i+1;j<sort.length;j++){
if(sort[j]<sort[i]){
int temp = sort[j];
sort[j] = sort[i];
sort[i] = temp;
}
}
}
}
}
三、快速排序
[java] view plain
package sort.quick;
/**
* 快速排序 通過一趟排序將要排序的數據分割成獨立的兩部分, 其中一部分的所有數據都比另外一部分的所有數據都要小,
* 然後再按此方法對這兩部分數據分別進行快速排序, 整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
* @author liangge
*
*/
public class Main {
public static void main(String[] args) {
int[] sort = { 54, 31, 89, 33, 66, 12, 68, 20 };
System.out.print("排序前的數組為:");
for (int data : sort) {
System.out.print(data + " ");
}
System.out.println();
quickSort(sort, 0, sort.length - 1);
System.out.print("排序後的數組為:");
for (int data : sort) {
System.out.print(data + " ");
}
}
/**
* 快速排序
* @param sort 要排序的數組
* @param start 排序的開始座標
* @param end 排序的結束座標
*/
public static void quickSort(int[] sort, int start, int end) {
// 設置關鍵數據key為要排序數組的第一個元素,
// 即第一趟排序後,key右邊的數全部比key大,key左邊的數全部比key小
int key = sort[start];
// 設置數組左邊的索引,往右移動判斷比key大的數
int i = start;
// 設置數組右邊的索引,往左移動判斷比key小的數
int j = end;
// 如果左邊索引比右邊索引小,則還有數據沒有排序
while (i < j) {
while (sort[j] > key && j > start) {
j--;
}
while (sort[i] < key && i < end) {
i++;
}
if (i < j) {
int temp = sort[i];
sort[i] = sort[j];
sort[j] = temp;
}
}
// 如果左邊索引比右邊索引要大,說明第一次排序完成,將sort[j]與key對換,
// 即保持了key左邊的數比key小,key右邊的數比key大
if (i > j) {
int temp = sort[j];
sort[j] = sort[start];
sort[start] = temp;
}
//遞歸調用
if (j > start && j < end) {
quickSort(sort, start, j - 1);
quickSort(sort, j + 1, end);
}
}
}
[java] view plain
/**
* 快速排序
*
* @param a
* @param low
* @param high
* voidTest
*/
public static void kuaisuSort(int[] a, int low, int high)
{
if (low >= high)
{
return;
}
if ((high - low) == 1)
{
if (a[low] > a[high])
{
swap(a, low, high);
return;
}
}
int key = a[low];
int left = low + 1;
int right = high;
while (left < right)
{
while (left < right && left <= high)// 左邊向右
{
if (a[left] >= key)
{
break;
}
left++;
}
while (right >= left && right > low)
{
if (a[right] <= key)
{
break;
}
right--;
}
if (left < right)
{
swap(a, left, right);
}
}
swap(a, low, right);
kuaisuSort(a, low, right);
kuaisuSort(a, right + 1, high);
}
四、插入排序
[java] view plain
package sort.insert;
/**
* 直接插入排序
* 將一個數據插入到已經排好序的有序數據中,從而得到一個新的、個數加一的有序數據
* 演算法適用於少量數據的排序,時間復雜度為O(n^2)。是穩定的排序方法。
*/
import java.util.Random;
public class DirectMain {
public static void main(String[] args) {
Random ran = new Random();
int[] sort = new int[10];
for (int i = 0; i < 10; i++) {
sort[i] = ran.nextInt(50);
}
System.out.print("排序前的數組為");
for (int i : sort) {
System.out.print(i + " ");
}
directInsertSort(sort);
System.out.println();
System.out.print("排序後的數組為");
for (int i : sort) {
System.out.print(i + " ");
}
}
/**
* 直接插入排序
*
* @param sort
*/
private static void directInsertSort(int[] sort) {
for (int i = 1; i < sort.length; i++) {
int index = i - 1;
int temp = sort[i];
while (index >= 0 && sort[index] > temp) {
sort[index + 1] = sort[index];
index--;
}
sort[index + 1] = temp;
}
}
}
順便添加一份,差不多的
[java] view plain
public static void charuSort(int[] a)
{
int len = a.length;
for (int i = 1; i < len; i++)
{
int j;
int temp = a[i];
for (j = i; j > 0; j--)//遍歷i之前的數字
{
//如果之前的數字大於後面的數字,則把大的值賦到後面
if (a[j - 1] > temp)
{
a[j] = a[j - 1];
} else
{
break;
}
}
a[j] = temp;
}
}
把上面整合起來的一份寫法:
[java] view plain
/**
* 插入排序:
*
*/
public class InsertSort {
public void sort(int[] data) {
for (int i = 1; i < data.length; i++) {
for (int j = i; (j > 0) && (data[j] < data[j - 1]); j--) {
swap(data, j, j - 1);
}
}
}
private void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
五、順便貼個二分搜索法
[java] view plain
package search.binary;
public class Main {
public static void main(String[] args) {
int[] sort = {1,2,3,4,5,6,7,8,9,10};
int mask = binarySearch(sort,6);
System.out.println(mask);
}
/**
* 二分搜索法,返回座標,不存在返回-1
* @param sort
* @return
*/
private static int binarySearch(int[] sort,int data){
if(data<sort[0] || data>sort[sort.length-1]){
return -1;
}
int begin = 0;
int end = sort.length;
int mid = (begin+end)/2;
while(begin <= end){
mid = (begin+end)/2;
if(data > sort[mid]){
begin = mid + 1;
}else if(data < sort[mid]){
end = mid - 1;
}else{
return mid;
}
}
return -1;
}
}

9. 面試官常問十大經典演算法排序(用python實現)

演算法是一種與語言無關的東西,更確切地說就算解決問題的思路,就是一個通用的思想的問題。代碼本身不重要,演算法思想才是重中之重

我們在面試的時候總會被問到一下演算法,雖然演算法是一些基礎知識,但是難起來也會讓人非常頭疼。

排序演算法應該算是一些簡單且基礎的演算法,但是我們可以從簡單的演算法排序鍛煉我們的演算法思維。這里我就介紹經典十大演算法用python是怎麼實現的。

十大經典演算法可以分為兩大類:

比較排序: 通過對數組中的元素進行比較來實現排序。

非比較排序: 不通過比較來決定元素間的相對次序。


演算法復雜度

冒泡排序比較簡單,幾乎所有語言演算法都會涉及的冒泡演算法。

基本原理是兩兩比較待排序數據的大小 ,當兩個數據的次序不滿足順序條件時即進行交換,反之,則保持不變。

每次選擇一個最小(大)的,直到所有元素都被輸出。

將第一個元素逐個插入到前面的有序數中,直到插完所有元素為止。

從大范圍到小范圍進行比較-交換,是插入排序的一種,它是針對直接插入排序演算法的改進。先對數據進行預處理,使其基本有序,然後再用直接插入的排序演算法排序。

該演算法是採用 分治法 對集合進行排序。

把長度為n的輸入序列分成兩個長度為n/2的子序列,對這兩個子序列分別採用歸並排序,最終合並成序列。

選取一個基準值,小數在左大數在在右。

利用堆這種數據結構所設計的一種排序演算法。

堆是一個近似完全二叉樹的結構,並同時滿足堆積的性質:即子結點的鍵值或索引總是小於(或者大於)它的父節點。利用最大堆和最小堆的特性。

採用字典計數-還原的方法,找出待排序的數組中最大和最小的元素,統計數組中每個值為i的元素出現的次數,對所有的計數累加,將每個元素放在新數組依次排序。

設置一個定量的數組當作空桶;遍歷輸入數據,並且把數據一個一個放到對應的桶里去;對每個不是空的桶進行排序;從不是空的桶里把排好序的數據拼接起來。

元素分布在桶中:


然後,元素在每個桶中排序:

取得數組中的最大數,並取得位數;從最低位開始取每個位組成新的數組;然後進行計數排序。

上面就是我整理的十大排序演算法,希望能幫助大家在演算法方面知識的提升。看懂之後可以去試著自己到電腦上運行一遍。最後說一下每個排序是沒有調用數據的,大家記得實操的時候要調用。

參考地址:https://www.runoob.com/w3cnote/ten-sorting-algorithm.html

10. 面試演算法題:你的任務就是計算出長度為n的字元串(只包含『A』、『B』和『C』),有多少個是暗黑字元串。

程序肯定不是判斷一個字元串是純潔的還是黑暗的。從現有的題目描述看,程序和題目沒有關系。

題目是否不全?

熱點內容
java返回this 發布:2025-10-20 08:28:16 瀏覽:593
製作腳本網站 發布:2025-10-20 08:17:34 瀏覽:888
python中的init方法 發布:2025-10-20 08:17:33 瀏覽:582
圖案密碼什麼意思 發布:2025-10-20 08:16:56 瀏覽:765
怎麼清理微信視頻緩存 發布:2025-10-20 08:12:37 瀏覽:684
c語言編譯器怎麼看執行過程 發布:2025-10-20 08:00:32 瀏覽:1013
郵箱如何填寫發信伺服器 發布:2025-10-20 07:45:27 瀏覽:255
shell腳本入門案例 發布:2025-10-20 07:44:45 瀏覽:114
怎麼上傳照片瀏覽上傳 發布:2025-10-20 07:44:03 瀏覽:806
python股票數據獲取 發布:2025-10-20 07:39:44 瀏覽:713