《劍指offer 有趣的陣列

2021-06-21 02:07:42 字數 3992 閱讀 3223

最近投簡歷,面試耽誤不少進度,有些迷茫,不知道自己究竟適不適合程式設計師這行業,半道出家的娃只能且走且看,演算法也只是突擊了兩個月,心裡實在沒地,覺得要是拿到那些cs大牛人不屑於顧的offer肯定歡天喜地 =_=

i am a slow walker, but i never walk backward.

【8旋轉陣列中的最小數】

//題目:把乙個陣列最開始的若干數字搬到陣列的末尾,我們稱之為陣列的旋轉。輸入乙個遞增的陣列

//輸出旋轉陣列的最小元素。例如:3,4,5,1,2是1,2,3,4,5,的乙個旋轉陣列,該陣列的最小值是1

//思路類似二分查詢,旋轉陣列的性質就是前半序列大於後半序列。

//首先設定三個指標,pl,pm,ph頭指標,中間指標和尾指標

//如果中間的數字大於頭指標,那麼證明最小的數在後半序列,在對後半序列進行遞迴

遞迴寫法

[cpp]view plain

copy

intget_min_reverse_array(

inta, 

intlow, 

inthigh)    

//非遞迴寫法

[cpp]view plain

copy

intsolu2_get_min_reverse_array(

inta, 

intlen)  

mid = (low+high)/2;  

if(a[mid] > a[low])  

low = mid;  

if(a[mid] < a[high])  

high = mid;  

}  return

a[mid];  

}  

//另外,上面寫法不完整,當碰見1 0 1 1 1的時候也就是三個指標的數相同時候,只能遍歷找到最小的數

【31連續子數列的最大和】

//題目:輸入乙個整數,裡面有正有負,陣列中乙個或者多個連續數形成乙個子串行,

//求所有子陣列中和的最大值,要求時間複雜度為o(n),這個需要慢慢分析,

//主要考慮前面累加的和為負值跟當前元素的關係,碰見負值如何處理

[cpp]view plain

copy

intget_max_subarray(

inta, 

intlen)  

return

max_sub_sum;  

}  

【32 從1到n中1出現的次數】

//題目輸入乙個整數n,求從1到n這n個整數十進位制表示中1出現的次數

//思路一,直接判斷每個數的每一位,時間複雜度是nlgn

[cpp]view plain

copy

long

long

count_1s(

long

n)  

return

cc;  

}  long

long

stupid_sum1s(

long

n)  

return

count;  

}  

//思路二

//@32 從1到n整數中出現1的次數,結論:假設abcde代表整數的每一位,c是百位,百位數為1的整數的總的個數分以下幾種情況

//百位為0的話,例如13045,百位上是1的數是 xx100~xx199 (x範圍00~12) 所以又13*100 = 1300

//百位為1的話,例如13145,百位上是1的數是 xx100~xx199 (x範圍00~12) 再加上13100~13145 一共有1300+145+1個

//百位大於1的話,如13245,百位上是1的數是 xx100~xx199 (x範圍00~13) 一共有(13+1)*100個

//理清楚了上面的思路在寫就很容易了 

[cpp]view plain

copy

long

long

sum1s(

long

n)  

return

count;  

}  

[cpp]view plain

copy

#include 

using

namespace

std;  

void

test_sum1s()    

【數字在排序中出現的次數】

//@38數字在排序陣列中出現的次數,注意是排序,比如1,2,3,4,4,4,4,4,6,9,10和4,返回4的個數5

//使用二分查詢,a[mid]不是4的話,跟一般的二分查詢沒區別,當a[mid]=4時候我們需要找到的是4的左右端點,看下

//規律,最左邊的端點前面的數字比這個數小,最右邊的端點右邊的數字比這個數大

[cpp]view plain

copy

intget_last_k(

inta, 

intlow, 

inthigh, 

intk)  

if(a[mid] > k)  

high = mid - 1;  

if(a[mid] < k)  

low = mid + 1;  

return

get_last_k(a, low ,high , k);  

}  int

get_first_k(

inta, 

intlow, 

inthigh, 

intk)  

if(a[mid] < k)  

low = mid + 1;  

if(a[mid] > k)  

high = mid - 1;  

return

get_first_k(a, low , high , k);  

}  int

get_num_of_k(

inta, 

intlen, 

intk)  

void

test_get_num_of_k()  

;  int

a1 = ;  

inta2 = ;  

cout(a)/

sizeof

(a[0]), 4)<

cout(a1)/

sizeof

(a1[0]), 4)<

cout(a2)/

sizeof

(a2[0]), 4)<

}  

【陣列中出現一次的兩個數】

//@40陣列中只出現一次的數,乙個陣列中,找出只出現一次的兩個數,除這兩個數以外,其餘的數都出現兩次。

//要求時間複雜度是o(n),空間複雜度是o(1)

//假設陣列中只有乙個這種元素,使用異或就可以搞定,因為陣列中相同的元素異或為0,最終得到的結果肯定是那個出現一次的元素

//兩個呢?兩個最後異或的結果肯定不是0,是兩個元素的結果,有什麼規律呢?

//比如5,和7,0101^0111 = 0010,按照這個思路來說,0101和0111的二進位制表示的倒數第二位肯定不一樣

//這樣,原陣列中可以按照倒數第二位是1或者0來分成兩組,兩個組內再分別異或,得到的兩個結果肯定是5和7

[cpp]view plain

copy

void

inta, 

intlen, 

int& diff_1, 

int& diff_2)  

tmp_or_res = 1(int

i = 0; i < len; i++)  

}  void

;  int

array1 = ;  

intarray2 = ;  

}  

劍指offer 陣列

資料是最簡單的資料結構,它佔據一塊連續的記憶體並按照順序儲存資料。建立陣列時,首先指點陣列的容量大小,然後根據大小分配記憶體。缺點 空間效率不高。經常有空閒的區域滅有得到充分利用。優點 時間效率很高。可以根據時間效率高的特點,來實現簡單的雜湊表 把陣列的下標設為雜湊表的鍵值,陣列中的每乙個數字設為雜...

劍指offer 陣列

public class 03 陣列中的重複數字 swap number,number i i return 1 交換 public void swap int number,int i,int j public class 03 陣列中的重複數字 return 1 public intfindre...

劍指offer 陣列

問題描述 在乙個二維陣列中 每個一維陣列的長度相同 每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否含有該整數。function find target,array return false 問題描述 在乙個長度...