不會(huì)算法?大廠可不是那么好進(jìn)的!

前言

今天聊聊掌握了不一定能拿到大廠 Offer,但不掌握一定進(jìn)不去大廠的神技「數(shù)據(jù)結(jié)構(gòu)與算法」。

為什么突然提到了數(shù)據(jù)結(jié)構(gòu)與算法呢?這要從一個(gè)朋友的吐槽開始。

我這位朋友一心想進(jìn)大廠,學(xué)歷還不錯(cuò)、能力也不錯(cuò),但就是拿不到大廠Offer。大家都勸他多刷 LeetCode ,把數(shù)據(jù)結(jié)構(gòu)與算法弄明白。他確實(shí)聽了,半年過去之后,現(xiàn)在基礎(chǔ)知識(shí)還行,一旦涉及圖、排序、遞歸這些高級(jí)一點(diǎn)的知識(shí)就完蛋了。


其實(shí)很多人都有遇到這種情況,算法到底有多重要呢?

數(shù)據(jù)結(jié)構(gòu)與算法是互聯(lián)網(wǎng)大廠的敲門磚,也是開發(fā)者精益求精、持續(xù)提升的內(nèi)功基礎(chǔ)。

面試為什么考算法?

無非是算法最能說明一個(gè)人的綜合實(shí)力。

而大廠考算法一般也會(huì)分兩步,第一步:讓你直接說思路;第二步:讓你實(shí)操寫代碼。


通過這兩步,就可以看出你的編程內(nèi)功是否深厚,除此之外還能多維度考察你的其他能力,比如:邏輯思維清晰與否、debug 能力如何、編碼習(xí)慣怎樣、是否能寫出可維護(hù)的代碼等等......

下面講一講算法的學(xué)習(xí)方法

第一部分:把“爛”代碼優(yōu)化為高效率代碼的方法和路徑,也是關(guān)于代碼開發(fā)與優(yōu)化方法框架的總綱。代碼的目標(biāo),除了完成任務(wù),還要求把某項(xiàng)任務(wù)高效率地完成。

第二部分,補(bǔ)充必備的數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)知識(shí)。時(shí)間/空間復(fù)雜度的降低,要求對(duì)數(shù)據(jù)有超強(qiáng)的組織方式,這些能力需要你對(duì)數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)知識(shí)有極為深刻的理解,只有理解了他們的優(yōu)劣才能靈活選用合適的數(shù)據(jù)結(jié)構(gòu)。

第三部分,這部分是你學(xué)習(xí)的重點(diǎn),也就是用算法思考問題的邏輯和程序設(shè)計(jì)方法。

第四部分,側(cè)重在 BAT 高頻面試真題詳解。

第五部分,面試現(xiàn)場(chǎng)。很多工程師有個(gè)共性問題,那就是明明有能力,卻說不出來,表現(xiàn)得就像是個(gè)初學(xué)者一樣。


其中,最最最重要的就是刷題了,百煉才能成鋼!!(重要的事兒多說幾遍。)

推薦幾個(gè)做編程題目的網(wǎng)站:

下面給大家分享一些算法題

題目:

在一個(gè)二維數(shù)組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請(qǐng)完成一個(gè)函數(shù),輸入這樣的一個(gè)二維數(shù)組和一個(gè)整數(shù),判斷數(shù)組中是否含有該整數(shù)。

分析:

根據(jù)題意畫了個(gè)簡(jiǎn)單的圖,首先我們要確定查找開始的位置,因?yàn)樗嵌S的數(shù)組,它的下標(biāo)變化是兩個(gè)方向的,根據(jù)四個(gè)邊界點(diǎn)來分析。

a b

c d

A:向下 增 ,向右 增

B:向左 減 ,向下 增

C:向上 減 ,向右 增

D:向左 減 ,向上 減

可以看出從B 或C點(diǎn)開始查找剛好可以構(gòu)建一個(gè)二叉查找樹。

二叉查找樹(Binary Search Tree),(又:二叉搜索樹,二叉排序樹)它或者是一棵空樹,或者是具有下列性質(zhì)的二叉樹: 若它的左子樹不空,則左子樹上所有結(jié)點(diǎn)的值均小于它的根結(jié)點(diǎn)的值; 若它的右子樹不空,則右子樹上所有結(jié)點(diǎn)的值均大于它的根結(jié)點(diǎn)的值; 它的左、右子樹也分別為二叉排序樹。

先確定二維數(shù)組的行數(shù)和列數(shù),把 查找值 與 二叉查找樹的根節(jié)點(diǎn)(B或者 C)開始比較,如果相等返回true,小于查找左子樹,大于就查找右子樹。如果遍歷超過數(shù)組邊界,就返回 false。

以C為根節(jié)點(diǎn)查找

public class Solution {
public boolean Find(int [][] array,int target) {

    int i = array.length -1;
    int m = array[0].length -1;
    int j = 0;

    while(i>=0 && j<=m){
        if(target == array[i][j]){
            return true;
        }else if(target >array[i][j]){
            j++;
        }else{
            i--;
        }
    }

    return false;
}

}
以B為根節(jié)點(diǎn)查找

public class Solution {
public boolean Find(int [][] array,int target) {

    int i = array.length -1;
    int j = array[0].length -1;
    int n = 0;

    while(j>=0 && n<=i){
        if(target == array[n][j]){
            return true;
        }else if(target >array[n][j]){
            n++;
        }else{
            j--;
        }
    }

    return false;
}

}
輸入一個(gè)整數(shù),輸出該數(shù)二進(jìn)制表示中1的個(gè)數(shù)。其中負(fù)數(shù)用補(bǔ)碼表示。
題目分析

解法一  運(yùn)行時(shí)間:29m  占用內(nèi)存:629k

public int NumberOf1(int n) {
String s=Integer.toBinaryString(n);
char[] c=s.toCharArray();
int j=0;
for(int i=0;i<c.length;i++){

            if(c[i]=='1'){
                j++;
            }

    }
    return j;
 }

}
解析:

public static String toBinaryString(int i)

以二進(jìn)制(基數(shù) 2)無符號(hào)整數(shù)形式返回一個(gè)整數(shù)參數(shù)的字符串表示形式。

①先把整數(shù)轉(zhuǎn)換成二進(jìn)制字符串

②把字符串轉(zhuǎn)換成字符數(shù)組

③遍歷該數(shù)組,判斷每位是否為1,為1 計(jì)數(shù)加1。

④遍歷完成返回1的個(gè)數(shù)

解法二 運(yùn)行時(shí)間:30ms 占用內(nèi)存:629k

public class Solution {
public int NumberOf1(int n) {
int count =0;
while(n!=0){
count++;
n = n&(n-1);
}
return count;
}
}
解析:

如果一個(gè)整數(shù)不為0,那么這個(gè)整數(shù)至少有一位是1。如果我們把這個(gè)整數(shù)減1,那么原來處在整數(shù)最右邊的1就會(huì)變?yōu)?,原來在1后面的所有的0都會(huì)變成1(如果最右邊的1后面還有0的話)。其余所有位將不會(huì)受到影響。

題目:
用兩個(gè)棧來實(shí)現(xiàn)一個(gè)隊(duì)列,完成隊(duì)列的Push和Pop操作。 隊(duì)列中的元素為int類型。

思路:
壓入元素直接壓入stack1 刪除元素先查看stack2是否為空,非空則彈出;空則將stack1中元素取出,置于stack2中

代碼:

public class StackQueue {

Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();

public void push(int node){
    stack1.push(node);
}

public int pop(){
    if(stack2.empty()){
        while(!stack1.empty())
            stack2.push(stack1.pop());
    }
    return stack2.pop();

}

遞歸和迭代的區(qū)別是什么,各有什么優(yōu)缺點(diǎn)?

程序調(diào)用自身稱為遞歸,利用變量的原值推出新值稱為迭代。
遞歸的優(yōu)點(diǎn)大問題轉(zhuǎn)化為小問題,可以減少代碼量,同時(shí)代碼精簡(jiǎn),可讀性好;
缺點(diǎn)就是遞歸調(diào)用浪費(fèi)了空間,而且遞歸太深容易造成堆棧的溢出。

迭代的好處就是代碼運(yùn)行效率好,因?yàn)闀r(shí)間只因循環(huán)次數(shù)增加而增加,而且沒有額外的空間開銷;
缺點(diǎn)就是代碼不如遞歸簡(jiǎn)潔

找不到學(xué)習(xí)資料怎么辦

有很多小伙伴他們其實(shí)都明白算法的重要性,也有去學(xué)習(xí)的心,可是苦于不知道從何處下手,身邊也沒有可以請(qǐng)教的人。

下面我就介紹一下我整理的學(xué)習(xí)資料。



最后

需要資料可以進(jìn)入我的gitee或者點(diǎn)擊這里免費(fèi)領(lǐng)取資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 表情是什么,我認(rèn)為表情就是表現(xiàn)出來的情緒。表情可以傳達(dá)很多信息。高興了當(dāng)然就笑了,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 129,475評(píng)論 2 7
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險(xiǎn)厭惡者,不喜歡去冒險(xiǎn),但是人生放棄了冒險(xiǎn),也就放棄了無數(shù)的可能。 ...
    yichen大刀閱讀 7,604評(píng)論 0 4

友情鏈接更多精彩內(nèi)容