算法(第四版)讀書筆記 第一章

y7## Java基礎(chǔ)

數(shù)組

創(chuàng)建數(shù)組

  1. 聲明數(shù)組的類型和名字
  2. 創(chuàng)建數(shù)組
  3. 初始化數(shù)組
double[] a; //聲明數(shù)組
a= new double[N];//創(chuàng)建數(shù)組
for(int i =0;i<N;i++){
    a[i] = 0.0
}//初始化數(shù)組
double[] a = new double[N];//簡寫

二維數(shù)組

靜態(tài)方法

調(diào)用

  1. 方法的參數(shù)按值傳遞
    參數(shù)變量的初始值是由調(diào)用方提供的,方法處理的是參數(shù)的值而非參數(shù)本身
  2. 方法名可以被重載
    重寫是子類的方法覆蓋父類的方法,要求方法名和參數(shù)都相同
    重載是在同一個類中的兩個或兩個以上的方法,擁有相同的方法名,但是參數(shù)卻不相同王悍,方法體也不相同,最常見的重載的例子就是類的構(gòu)造函數(shù),可以參考API幫助文檔看看類的構(gòu)造方法
  3. 方法只能返回一個值
    返回被執(zhí)行的第一條語句的返回值
  4. 返回值可以是void

遞歸

API

Math的參數(shù)都是double類型纲熏,返回值也是double,因此可以將它們看做是double的擴展

字符串

  1. "+"可以拼接字符串
  2. 類型轉(zhuǎn)換
    paseInt() toString() parseDouble()

i/o

標(biāo)準(zhǔn)輸出(StdOut)

printin()附加一個換行符
printf()格式化輸出

命令行語句

javac .java 編譯java文件
java .class 運行Java程序

格式化輸出

printf()有兩個參數(shù)

  1. 格式化字符
    %跟著字符的轉(zhuǎn)換代碼(d(十進(jìn)制),f(浮點型)局劲,s(字符串))勺拣,在%和代碼之間可以添加一個整數(shù)表示輸出字符串的長度,還可以插入一個小數(shù)點表示轉(zhuǎn)換后double保留的位數(shù)或是string字符串截取的長度鱼填。\n為換行
  2. 要輸出的變量

標(biāo)準(zhǔn)輸入(StdIn)

Api
  1. isEmpty 沒有剩余值就返回true药有,有就返回false
  2. readInt
  3. readDouble
    ...

基于文件的輸入輸出(In/Out)

public calss In

  1. readInts()
  2. readDoubles()
  3. readString()
    public class Out
  4. write(int[])
  5. write(double[])
  6. write(String[])

標(biāo)準(zhǔn)繪圖庫(StdDrw)

注意

  1. for()頭部的代碼和主體代碼是一個作用域,while不是
  2. 聲明數(shù)組 int[] a ,int a[]
  3. ptintIn(in[] a)輸出的是他的地址
  4. 靜態(tài)方法不能將另一個靜態(tài)方法做參數(shù)

Week 1 union-find并查集問題

知識點

  1. 貪心算法 greedy algorithm
  2. connected component 連通組件(圖論)

快速排序的Java實現(xiàn)

package com.algs4;

public class QuickFind {
    private int [] id;
    //set id of each object to itself
    public QuickFind(int N){
        id = new int[N];
        for (int i = 0; i < N; i++) {
            id[i] = i;
        }
    }
    //check weather p and q in same component 
    public boolean connect(int p,int q){
        return id[p] == id [q]; 
    }
    //change all entries with id[p] to id[q]
    public void union(int p, int q){
        int pid = id[p];
        int qid = id[q];
        for (int i = 0; i < id.length; i++) {
            if (id[i] == pid) {
             id[i] = qid;
            }
        }
    }
}
//o(n^2)

但是quickfind對于數(shù)據(jù)量很大的數(shù)據(jù)來說就太慢了
優(yōu)化1: 快速合并的替代替代算法 ‘Lazy approach’
把上面的數(shù)據(jù)結(jié)構(gòu)中的一組數(shù)看做“樹”

public class Quickunion {
    private int[] id;
    //set object to item
    public Quickunion(int N){
        for (int i = 0; i < N; i++) {
            id = new int[N];
            id[i] = i;
        }
    }
    //通過回朔苹丸,尋找根節(jié)點愤惰,id[i] = i;就是根節(jié)點,如果不是,就把i在樹上上移一層赘理,把i設(shè)為i的id
    private int root(int i){
        while(i != id[i]) id[i] = i;
        return i;
    }
    //判斷根節(jié)點是否相等
    public boolean connect(int p,int q){
        return root(p) == root (q);
    }
    public void union(int p,int q){
        int i = root(p);
        int j = root(q);
        id[i] = i;
    }
}

quickunion有時候快宦言,但有時候太慢了,因為樹太高了商模。查找操作代價太大了奠旺,可能要回朔一顆瘦長的樹,每個對象只是指向下一個節(jié)點施流,對子節(jié)點進(jìn)行一次查找响疚,就要回朔整個樹,操作次數(shù)多了就滿了

上面兩種都不支持巨大的連通性問題

新的:quickunionimprovement

這時引入了一種新的方法嫂沉,叫帶權(quán)(weighting),在執(zhí)行快速合并算法的時候執(zhí)行一些操作避免很深的樹稽寒,如果將大樹和小樹合并的時候,要避免把大樹放在下面趟章,避免得到更高的樹杏糙。
實現(xiàn):跟蹤每棵樹中對象的個數(shù),然后我們會使小樹的根節(jié)點作為大樹的子節(jié)點蚓土。這樣樹的深度最多也只有四層
維護一個sz數(shù)組宏侍,在union操作中比較sz的大小,然后合并蜀漆,時間復(fù)雜度為 lg(n)

public class QuickunionIm {
    private int[] id;
    private int[] sz; //維護一個sz數(shù)組谅河,在union操作中比較sz的大小,然后合并
    //set object to item
    public QuickunionIm(int N){
        for (int i = 0; i < N; i++) {
            id = new int[N];
            id[i] = i;
        }
    }
    //通過回朔确丢,尋找根節(jié)點绷耍,id[i] = i;就是根節(jié)點,如果不是,就把i在樹上上移一層鲜侥,把i設(shè)為i的id
    private int root(int i){
        while(i != id[i]) id[i] = i;
        return i;
    }
    //判斷根節(jié)點是否相等
    public boolean connect(int p,int q){
        return root(p) == root (q);
    }
    public void union(int p,int q){
        int i = root(p);
        int j = root(q);
        if (i == j) return ;
        if (sz[i] < sz[j]){
            id[i] = j;sz[j] += sz[i]; 
        }
        else{
            id[j] = i; sz[i] += sz[j];
        }
    }
}

improve2

cath compression 路徑壓縮
回溯一次路徑找到根節(jié)點褂始,然后再回溯將樹展平,時間復(fù)雜度是接近線性的,那是否有時間復(fù)雜度為線性的呢描函?但最后有人證明合并算法沒有線性的

//add second loop to root() to set the id[] of each examined node to root
public class Quickunionim2 {
    private int[] id;
    private int root(int i){
        while( i != id[i]){
            id[i] = id[id[i]];
            i = id[i];
        }
        return i;
    }
}

并查集算法的應(yīng)用

滲濾(percolation) 上下是存在開放位崎苗,且聯(lián)通的,系統(tǒng)是否滲透的p的闕值十分陡峭狐粱,要求那個值必須用計算機仿真,蒙特卡洛仿真胆数。

算法分析

FFT 快速傅里葉變換算法肌蜻,將算法信號的N個采樣波形分為若干周期分量。DVD和JPEG的基礎(chǔ)必尼,將復(fù)雜度從N^2將為N*logN

3sum問題

簡單的n^3

public class three_SUM {
    public static int count(int[] a){
        int N = a.length;
        int count = 0;
        for (int i = 0; i < a.length; i++) {
            for (int j = i+1; j < a.length; j++) {
                for (int j2 = j+1; j2 < a.length; j2++) {
                    if (a[i] + a[j] +a[j2] == 0) {
                        count ++;
                    }
                }
            }
        }
        return count;
    }
    public void main(String[] args){
        int[] a = In.readInts(args[0]);
        StdOut.println(count(a));
        } 
}

n^3 -> n^2longn

Java標(biāo)準(zhǔn)庫里面有一個秒表類蒋搜,可以計算用掉的時間

Stopwatch stopwatch = new Stopwatch();
double time = stopwatch.elapseTime();

log-log坐標(biāo)系的的斜率為B,則正比于 N^b


一般的時間復(fù)雜度

  1. 常數(shù) 沒有循環(huán)
  2. logN 被分成兩半(二叉樹查找) 時間增長也是常數(shù)
  3. N 遍歷了所有元素 1SUM
  4. NlogN 分治法 ——>并歸排序
  5. N^2 兩次遍歷
  6. 2^n

type of analyses

  1. 總考慮最壞的case
  2. 總考慮最好的case

~ 表示近似模型

  1. Θ記號就是表示增長階數(shù)的方法 Θ(N2)就是某個常數(shù)乘以N2的簡寫判莉。它的上下界都是常數(shù)乘以N^2齿诞。這就是我們實際用來對算法分類的記號
  2. 接下來是O記號,它是算法性能的上界比如O(N2)就表示當(dāng)N增長時骂租,運行時間小于某個常數(shù)乘以N2
  3. Ω用來表示下界,Ω(N2)表示當(dāng)N增長時運行時間比某個常數(shù)乘以N2大斑司。

內(nèi)存

8個比特是一個字節(jié)渗饮。一百萬比特是2的20次方個,十億比特是2的30次方我們通常使用2^20表示兆字節(jié)MB∷薰危現(xiàn)在老的計算機我們用了很多年的32位系統(tǒng)互站,里面的指針是4個字節(jié)的。近幾年我們基本都遷移到了新的計算模型僵缺,機器是64位的 指針是8個字節(jié)胡桃。

  1. bollan只占一個比特
  2. 字符占兩個字節(jié),16位的字符也就是16比特
  3. 普通int整型是四個字節(jié)或者32位磕潮。
  4. 單精度浮點型也是4個字節(jié)翠胰。
  5. 長整型和雙精度浮點型是8個字節(jié) 大多數(shù)應(yīng)用中,我們使用雙精度浮點型表示浮點數(shù)自脯,普通整型表示整數(shù)
  6. 對于數(shù)組之景,需要一定量的額外空間加上,如果有N個元素膏潮,基本類型的空間開支乘以N 所以長度為N的雙精度浮點型數(shù)組需要的空間是8N+24锻狗。
  7. 二維數(shù)組需要的空間近似于8MN,額外空間還有一項但是對于大M和N這個式子就很準(zhǔn)確了焕参。
  8. 引用的開銷還有典型實現(xiàn)中內(nèi)置的用來對齊的空間使得每個對象占據(jù)的空間是8字節(jié)的倍數(shù) 例如轻纪,如果有一個日期對象,它有三個整型實例變量這個對象總共占據(jù)32字節(jié)叠纷。每個整型占據(jù)4個字節(jié)對象額外空間占16個字節(jié)刻帚,為了對齊需要4個字節(jié),所以總共占32個字節(jié)

數(shù)據(jù)抽象

java編程主要是通過class構(gòu)建被稱為引用類型的數(shù)據(jù)類型讲岁,也被稱為oop我擂,也就是面向?qū)ο缶幊坛囊裕幢3至四硞€數(shù)據(jù)類型的實體。
數(shù)據(jù)抽象(ADT)是一種能對使用者隱藏數(shù)據(jù)表示的數(shù)據(jù)類型校摩。他的特點在于將數(shù)據(jù)和函數(shù)實現(xiàn)了關(guān)聯(lián)看峻,我們在使用數(shù)據(jù)類型時更加注重API操作;在實現(xiàn)數(shù)據(jù)類型時衙吩,我們專注于數(shù)據(jù)本身以及對數(shù)據(jù)的操作互妓。
在這門課中我們要學(xué)會在不修改用例代碼的情況下,用另一種算法替換并對實現(xiàn)性能提升

基本數(shù)據(jù)類型的算法和數(shù)據(jù)結(jié)構(gòu)

stack and queues and bag(棧和隊列和背包)

stack(棧)

后入先出 (FIFO)

public class stack<item>
    stack()  創(chuàng)建一個新棧
    void push (入棧 ) 插入元素  
    item pop (出棧)除去元素
    boolean isEmpty() 棧是否為空
    int size() 棧中元素的數(shù)量

queue(隊列)

先入先出 下壓(LIFO)

public class queue<item>
    Queue() 創(chuàng)建一個新隊列
    enqueue()(入隊)加入元素 
    dequeue()  (出隊)除去元素 
    boolean isEmpty() 是否為空
    int size() 元素的數(shù)量

bag (背包)

public class Bag<item>
    Bag()  創(chuàng)建一個新背包
    void add(Item item)  添加一個元素
    boolean isEmpty() 是否為空
    int size() 元素

泛型和迭代

泛型

集合類數(shù)據(jù)抽象的一個關(guān)鍵特性就是我們可以用它儲存任意類型的數(shù)據(jù)坤塞。java里面有一種特殊的機制能完成這項工作冯勉,我們稱之為泛型,也叫做參數(shù)化類型。
上面的API當(dāng)中類名后的<item>將item定義為一個類型參數(shù)摹芙,他是一個占位符灼狰,表示將使用某個數(shù)據(jù)類型「『蹋可以將Stack<item>理解為某個元素的棧交胚。

Stack<String> stack = new Stack<String>();
stack .push('Test');
Stack next = stack.pop();

自動裝箱

類型參數(shù)都必須實例化為引用類型,因此JAVA有一種特殊的機制(類型轉(zhuǎn)換)使泛型代碼處理原始數(shù)據(jù)類型盈电。在處理 賦值語句蝴簇,方法的參數(shù)和算數(shù)邏輯表達(dá)式時候,java會在引用類型和原始類型之間進(jìn)行轉(zhuǎn)換匆帚。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末熬词,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吸重,更是在濱河造成了極大的恐慌互拾,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嚎幸,死亡現(xiàn)場離奇詭異摩幔,居然都是意外死亡,警方通過查閱死者的電腦和手機鞭铆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門或衡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人车遂,你說我怎么就攤上這事封断。” “怎么了舶担?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵坡疼,是天一觀的道長。 經(jīng)常有香客問我衣陶,道長柄瑰,這世上最難降的妖魔是什么闸氮? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮教沾,結(jié)果婚禮上蒲跨,老公的妹妹穿的比我還像新娘。我一直安慰自己授翻,他們只是感情好或悲,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著堪唐,像睡著了一般巡语。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上淮菠,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天男公,我揣著相機與錄音,去河邊找鬼合陵。 笑死理澎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的曙寡。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼寇荧,長吁一口氣:“原來是場噩夢啊……” “哼举庶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起揩抡,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤户侥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后峦嗤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蕊唐,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年烁设,在試婚紗的時候發(fā)現(xiàn)自己被綠了替梨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡装黑,死狀恐怖副瀑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情恋谭,我是刑警寧澤糠睡,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站疚颊,受9級特大地震影響狈孔,放射性物質(zhì)發(fā)生泄漏信认。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一均抽、第九天 我趴在偏房一處隱蔽的房頂上張望嫁赏。 院中可真熱鬧,春花似錦到忽、人聲如沸橄教。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽护蝶。三九已至,卻和暖如春翩迈,著一層夾襖步出監(jiān)牢的瞬間持灰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工负饲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留堤魁,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓返十,卻偏偏與公主長得像妥泉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子洞坑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容