劍指offer 學習筆記 陣列

2021-10-02 07:09:59 字數 3287 閱讀 6618

int

getsize

(int data)

intmain()

; cout <<

sizeof

(data)

<< endl;

int*p = data;

cout <<

sizeof

(p)<< endl;

cout <<

getsize

(data)

<< endl;

return0;

}

以上**輸出為20 4 4,sizeof(data)求的是陣列大小,p雖然和陣列名一樣能代表指向第乙個元素的指標,但本質上它只是指標,在32位下佔4位元組。c/c++中當陣列作為函式的引數傳遞時,陣列自動退化為同型別的指標,因此函式返回值為4。

面試題3:陣列中重複的數字

(1)在乙個長度為n的陣列裡的所有數字都在0~n-1的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意乙個重複的數字。例如,如果輸入長度為7的陣列,那麼對應的輸出是重複的數字2或者3。

方法一:將陣列排序,然後從排序的陣列中可以很快找到重複數字。排序乙個長度為n的陣列需要o(nlogn)的時間。

方法二:雜湊表,從頭到尾順序掃瞄陣列,每掃瞄到乙個元素時,都可以用o(1)的時間判斷雜湊表中是否已經有該數字,如果沒有就將這個數字加入雜湊表,如果雜湊表裡已經存在該數字,就找到。此演算法時間複雜度為o(n),但它提公升的時間效率是以乙個大小為o(n)的雜湊表為代價的。

方法三:從頭到尾依次掃瞄陣列中每個數字,當掃瞄到下標為i的數字m時,首先比較i和m是否相等,如相等,則掃瞄下乙個數字,如不相等,將下標為m的數字與m進行比較,如果相等,則找到乙個重複數字(此數字在下標m和i處都出現了),如不相等,就把下標是m的數字和m交換,這樣m就到了屬於它的位置。接下來繼續重複比較、交換這個過程,直到找到重複數字:

#include

using

namespace std;

bool

duplicate

(int nums,

int length,

int* duplication)

for(

int i =

0; i < length;

++i)

}for

(int i =

0; i < length;

++i)

else}}

return

false;}

intmain()

;int duplication =-1

;if(duplicate

(data,

sizeof

(data)

/sizeof

(*data)

,&duplication)

)return0;

}

總的時間複雜度為o(n),空間複雜度為o(1)。

(2)在乙個長度為n+1的陣列裡,所有數字都在1~n的範圍內,所以陣列中至少有乙個數字是重複的。請找出陣列中任意乙個重複的數字,但不能修改輸入的陣列。例如,如果輸入長度為8的陣列,那麼對應的輸出是重複的數字2或者3。

方法一:建立乙個長度為n+1的輔助陣列,然後逐一把數字複製到輔助陣列。如果被複製的數字是m,那麼就把它複製到輔助陣列下標為m的位置,如果這個位置已經有值,那麼就能發現重複的數字了。這個方案需要o(n)的輔助空間,時間複雜度為o(n)。

方法二:把從1~n的數字從中間的數字m分為兩部分,前面一半為1~m,後面一半為m+1~n。如果1~m的數字數目超過m,那麼這一半的區間裡一定包含重複的數字,否則另一半m+1~n的區間裡一定包含重複的數字:

#include

using

namespace std;

intcountrange

(int nums,

int length,

int start,

int end)

}return count;

}int

dup(

int nums,

int length)

int start =1;

// 最小值為1

int end = length -1;

// 最大值為n

while

(start <= end)

else}if

(count > middle - start +1)

else}}

intmain()

;int length =

sizeof

(data)

/sizeof

(*data)

;int duplication =

dup(data, length);if

(duplication !=-1

)return0;

}

這種方法按二分法思路,countrange函式被呼叫o(logn)次,每次需o(n)時間,總的時間複雜度為o(nlogn),空間複雜度為o(1),與第一種方法相比,相當於以時間換空間。並且這個方法不能找出所有的重複數字。

二維陣列的查詢:在乙個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序,請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否含有該整數:

方法:首先選取陣列中右上角的數字,如果該數字等於要查詢的數字,則查詢過程結束;如果該數字大於要查詢的數字,則剔除這個數字所在的列;如果該數字小於要查詢的數字,則剔除這個數字所在的行:

#include

using

namespace std;

bool

find

(int

* matrix,

int columns,

int rows,

int number)

int row =0;

int column = columns -1;

while

(row < rows && column >=0)

else

if(matrix[row * columns + column]

< number)

else

}return

false;}

intmain()

; cout <<

find

(nums,3,

3,8)

<< endl;

return0;

}

劍指offer學習筆記

筆記主要記錄方法和知識點 知識點1 負數與補碼 乙個參考 知識點2 移位操作 右移 變小 按位 操作 知識點3 0xffffffff表示32位 1 o logn 的方法 非遞迴的快速冪,用到二進位制表示。在迴圈內注意base base。兩個指標等間距一起走。想明白斷開鍊錶這個事情,相當於操作是在原有...

劍指offer 學習筆記 數值的整數次方

由於精度原因,判斷兩個小數是否相等不能用 int main 以上 輸出0的原因是十進位制轉換為二進位制會損失精度,由於0.1轉換為二進位制結果為0.00011001100 無限迴圈,因此在double容量有限的情況下計算機只能近似存放,但0.5就可以轉換為二進位制0.1,就可以精確存放。當對無法精確...

劍指offer 陣列

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