劍指offer(1):數組
1 寫作計劃
最近在看《劍指offer》,發現自己有很多的數據結構與算法的基礎知識要復習,《好書一起讀(131):讓寫作更好》中提到用寫作倒逼閱讀,我很是贊同。所以,計劃以《劍指offer》為中心,以記錄復習心得目的,寫一系列數據結構與算法的文章。
- 文章結構
文章從概念介紹切入,接著介紹相關的語言細節(以C語言和Python為主),最後以《劍指offer》中的編程題做結。
2 什麽是數組
一提到數組,我第一時間經典的C語言實現和與之對應的一片定長連續的內存空間。數組的讀寫操作很快,時間復雜度為o(1),但是因其必須事先指定長度,所以空間利用率不高。數組的下標是數組中元素的標識,可以當做元素的身份證使用,在需要記錄大量數據時,要利用好數組下標。
3 C語言細節
該節分3個部分介紹C語言從數組的必要語言細節。
3.1 數組越界問題
C語言不強制檢查數組下標是否越界,使用時應時刻註意越界問題。
這個是一個毫無意義的問題,因為C語言根本不允許數組越界。
數組越界是一種Undefined behavior,C語言沒規定程序運行結果,編譯器也不保證這個結果。C語言規定這種錯誤編譯器不必指出,所以編譯可能會正常通過,但這依然是一種錯誤,且責任在CODER。
因此這是一個毫無意義的問題,就如同問襪子燉茄子會是什麽味道。只有傻逼才會用襪子燉茄子然後親自嘗嘗——這就是那個“解答”的本質。作者:薛非
鏈接:https://www.zhihu.com/question/22897368/answer/22999166
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。
3.2 數組與指針
本節介紹數組與指針之間的關系以及數組在使用中的註意點。
數組名是特殊的指針
本節介紹數組與指針的共同點和不同點。
以數組int a[10];
為例:
int a[10];
int n = 10;
int a[n]; //定義數組時,長度不可以為變量,該語句非法
共同點:通過指針訪問數組元素
a[i]
與*(a+i)
、&a[i]
和a+i
都是等價的。- 通過等價指針訪問數組
int *pa;
pa = &a[0]; //指針pa指向數組的0元素地址
pa = a; //這個寫法和上句等價
x = *(pa+1);
x = a[1];
//這兩句賦值語句等價
不同點:數組名與指針的區別
指針是一個變量,但是數組名不是變量。
int *pa;
pa = &a[0]; //指針pa是可以被賦值的,其指向地址可以改變
int b[10];
a = b; //a不可以被賦值,該語句非法
函數中傳遞的數組是指針(地址)
- 以《劍指offer》中的代碼為例:
int GetSize(int data[])
{
return sizeof(data);
}
int main()
{
int data1[] ={1, 2, 3, 4, 5};
int size1 = sizeof(data1); //此處求數組data1所占字節數
int *data2 = data1;
int size2 = sizeof(data2); //此處求指針data2所占字節數
int size3 = GetSize(data1); //data1的地址被賦值給了局部變量data,所以返回指針data所占字節數
printf("%d, %d, %d", size1, size2, size3);
}
//輸出結果為:20, 4, 4
- 傳遞部分數組
利用數組以指針形式傳遞的特性,我們可以數組的後本部分給函數。如f(&a[3])
和f(a+3)
,將數組a的後7個元素傳遞給了函數f。
3.3 數組與哈希表
數組可以看做一個簡單的哈希表,其哈希函數為,為元素的關鍵字key。
常用的哈希函數有:
- 除法哈希法
不太接近2的整數冪的素數適合作為的值 - 乘法哈希法
其中是取的小數部分,即。
建議的變量取值為:;。 - 全域哈希法
隨機地選擇哈希函數,使之獨立於要存儲的關鍵字。在此不做詳細介紹。
4 編程題
在線編程資源
牛客網在線編程二維數組中的查找
Python:
# -*- coding:utf-8 -*-
class Solution:
# array 二維列表
def Find(self, target, array):
# write code here
r, c = len(array), len(array[0])
i, j = 0, c - 1 //選擇合適的開始位置,右上角和左下角都可以
while (i < r and j >= 0):
if target < array[i][j]:
j = j - 1
elif target > array[i][j]:
i = i + 1
else:
return True
return False //之前將return放在while循環中,一直通不過
C語言:
C語言的實現和Python大同小異,牛客網的OJ系統貌似不支持C語言,此處略過。
5 結語
正如《黑客與畫家》所說,編程語言是程序員的思考方式。思考問題的方式是在具體語言的基礎上進行的,如數組,用C語言思考,我看到的是一片定長連續的內存空間;用Python思考,我看到是隨意組合操作的不定長序列,學習不同的語言可以從不同的角度理解同一個概念,打破自己的思維局限。
劍指offer(1):數組