【劍指offer】1~10題

第一題:

在一個二維數(shù)組中会油,每一行都按照從左到右遞增的順序排序蛤高,每一列都按照從上到下遞增的順序排序。請完成一個函數(shù)籍茧,輸入這樣的一個二維數(shù)組和一個整數(shù)版述,判斷數(shù)組中是否含有該整數(shù)。

????這是非常簡單的一道題寞冯,最常規(guī)的一種方式就是兩個方向上掃描渴析,但是要保證其中一個掃描方向數(shù)字是遞增的,而另外一個方向上數(shù)字是遞減的吮龄。
????下面給出我的解法俭茧,從矩陣中的右上角開始,從右往左掃漓帚,當(dāng)橫向當(dāng)前數(shù)的下一個數(shù)小于目標(biāo)數(shù)的時候往下少母债,找到返回true,越界返回false尝抖。

public class Solution {
    public boolean Find(int target, int [][] array) {
        for(int i = array[0].length-1; i >= 0; i--) {
            if(array[0][i] <= target) {
                for(int j = 0; j < array.length; j++) {
                    if(array[j][i] == target) return true;
                }
            }
        }
        return false;
    }
}

第二題

請實(shí)現(xiàn)一個函數(shù)毡们,將一個字符串中的空格替換成“%20”。例如昧辽,當(dāng)字符串為We Are Happy.則經(jīng)過替換之后的字符串為We%20Are%20Happy衙熔。

????這題不解釋了,太簡單搅荞,很多編程語言直接用字符串處理函數(shù)就能做了红氯,用正則也能做,當(dāng)然咕痛,題目本身可能并不希望你這么干痢甘。

public class Solution {
    public String replaceSpace(StringBuffer str) {
        char[] arr = str.toString().toCharArray();
        int len = arr.length;
        int blankCount = 0;
        for(int i = 0; i < len; i++) {
            if(arr[i] == ' ')
                blankCount++;
        }
         
        int[] res = new int[len+blankCount];
        int j = 0;
        for(int i = 0; i < len; i++) {
            if(arr[i] == ' ') {
                res[j++] = '%';
                res[j++] = '2';
                res[j++] = '0';
            } else {
                arr[j++] = arr[i];
            }
        }
         
        StringBuffer sb = new StringBuffer();
        for(int i = 0; i < res.length; i++) {
            sb.append(res[i]);
        }
        return sb.toString();
    }
}

第三題

輸入一個鏈表,從尾到頭打印鏈表每個節(jié)點(diǎn)的值茉贡。

????最簡單的思路就是用棧倒序輸出塞栅。

public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> list = new ArrayList<>();
        Stack<Integer> stack = new Stack<>();
        while(listNode != null) {
            stack.push(listNode.val);
            listNode = listNode.next;
        }
        while(!stack.isEmpty()) {
            list.add(stack.pop());
        }
        return list;
    }
}

第四題

輸入某二叉樹的前序遍歷和中序遍歷的結(jié)果,請重建出該二叉樹腔丧。假設(shè)輸入的前序遍歷和中序遍歷的結(jié)果中都不含重復(fù)的數(shù)字构蹬。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹并返回悔据。

????總算來了個比較有意思的題目庄敛。給你前序和中序,讓你重構(gòu)二叉樹返回科汗。我們直接按題目中給的例子來講藻烤。
????前序遍歷是{1,2,4,7,3,5,6,8},也就是說 {1}這個數(shù)字就是根盖喷。而中序遍歷是{4,7,2,1,5,3,8,6}沐悦,從而可以劃出兩個子集{4,7,2,1} {5,3,8,6}分別為組成以{1}為根的左右子樹。
????依照這個邏輯下去叹谁,就可以得出整棵樹的結(jié)構(gòu)了兴猩。這顯然就是一些重復(fù)步驟期吓,用遞歸去做是最好的方式。再進(jìn)一步思考倾芝,我們只需要知道前序和中序遍歷的邊界下標(biāo)讨勤,就能在遞歸過程中計算出我們要得到的數(shù)據(jù)。接下來晨另,讓我們直接看代碼潭千。

public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        return rebuilder(pre, in, 0, pre.length-1, 0, in.length-1);
    }
    
    public TreeNode rebuilder(int[] pre, int[] in, int prel, int prer, int inl, int inr) {
        if(prel > prer) return null;
        TreeNode node = new TreeNode(pre[prel]);
        for(int i = inl; i <= inr; i++) {
            if(in[i] == pre[prel]) {
                node.left = rebuilder(pre, in, prel+1, prel+i-inl, inl, i-1);
                node.right = rebuilder(pre, in, prel+i-inl+1, prer, i+1, inr);
                break;
            }
        }
        return node;
    }
}

第五題

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

????也是非常簡單的一題。要用兩個棧模擬隊(duì)列路翻,我們只需要保持兩個原則狈癞。第一,當(dāng)你要push一個元素到其中一個棧時候茂契,另外一個棧必須為空蝶桶。第二,當(dāng)你要pop一個元素的時候账嚎,必須把棧中的所有元素傾倒到另外一個空棧莫瞬,然后再pop數(shù)據(jù)出去儡蔓。

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        while(!stack2.isEmpty()) {
            stack1.push(stack2.pop());
        }
        stack1.push(node);
    }
    
    public int pop() {
        while(!stack1.isEmpty()) {
            stack2.push(stack1.pop());
        }
        return stack2.pop();
    }
}

第六題

把一個數(shù)組最開始的若干個元素搬到數(shù)組的末尾郭蕉,我們稱之為數(shù)組的旋轉(zhuǎn)。 輸入一個非遞減排序的數(shù)組的一個旋轉(zhuǎn)喂江,輸出旋轉(zhuǎn)數(shù)組的最小元素召锈。 例如數(shù)組{3,4,5,1,2}為{1,2,3,4,5}的一個旋轉(zhuǎn),該數(shù)組的最小值為1获询。 NOTE:給出的所有元素都大于0涨岁,若數(shù)組大小為0,請返回0吉嚣。

????咋看之下梢薪,這題似乎掃描一遍數(shù)組就行了。沒錯尝哆,確實(shí)如此秉撇,但是題目本身是希望你用二分去做的,不然給你非遞減這個特性就沒有意義了。題目說琐馆,非遞減數(shù)列做旋轉(zhuǎn)规阀,旋轉(zhuǎn)之后其實(shí)主要有兩種情況,一種就是旋轉(zhuǎn)后和旋轉(zhuǎn)前一樣瘦麸,一種是旋轉(zhuǎn)后和選擇前發(fā)生了變化(這里暫時忽略數(shù)列中過的數(shù)全部相等的情況)谁撼,第一種情況,數(shù)列的最后一個數(shù)一定是大于第一個數(shù)的滋饲。第二種情況厉碟,最小的數(shù)一定在數(shù)列中。而這個數(shù)列也會分成兩個遞增的子數(shù)列了赌,且兩個子序列相連的邊界數(shù)字一定是遞減的墨榄,比如:{3,4,5} {1, 2}兩個遞增數(shù)列,5和1這兩個邊界是下降的勿她,從而我們可以得到二分的條件袄秩,假設(shè):當(dāng)前位置為i,那么當(dāng)a[i-1] > a[i]時逢并, i就是最小的數(shù)之剧。

public class Solution {
    public int minNumberInRotateArray(int [] array) {
        return binarySearch(array, 0, array.length-1);
    }
    /**
          大體上就是一個二分搜索,注意搜索條件即可
    */
    public int binarySearch(int[] arr, int l, int r) {
        
        if (arr[0] < arr[arr.length - 1])
            return arr[0];

        int mid = (l + r) / 2;
        // 這一句就是為了覆蓋數(shù)列數(shù)字全部相等的情況
        if(mid == r) return arr[r];
        if (arr[mid] < arr[mid - 1])
            return arr[mid];
        
        int res = 0;
        if(l <= r) {
            if (arr[mid] < arr[l])
                res = binarySearch(arr, l, mid);
            else
                res = binarySearch(arr, mid, r);
        }
        return res;
    }
}

第七題

大家都知道斐波那契數(shù)列砍聊,現(xiàn)在要求輸入一個整數(shù)n背稼,請你輸出斐波那契數(shù)列的第n項(xiàng)。
n<=39
????這題沒啥好講的玻蝌,為了避免爆棧蟹肘,應(yīng)該采用迭代的方式。

public class Solution {
    public int Fibonacci(int n) {
        if(n == 0)
            return 0;
        if(n == 1)
            return 1;
         
        int count = 1;
        Queue<Integer> queue = new LinkedList<Integer>();
        queue.add(0);
        queue.add(1);
        int res = -1;
        while(count != n) {
            res = queue.poll() + queue.peek();
            queue.add(res);
            count++;
        }
        return res;
    }
}

第八題

一只青蛙一次可以跳上1級臺階俯树,也可以跳上2級帘腹。求該青蛙跳上一個n級的臺階總共有多少種跳法。

????這題考察的就是一個遞推的是個思想许饿。假設(shè)i表示青蛙要跳上的臺階阳欲,當(dāng)i==1時,只有一種方法陋率;當(dāng)i==2時球化,可以從上一個臺階,或上上一個臺階跳上去瓦糟,所有有兩種方式筒愚,從而可以知道,當(dāng)i > 1時菩浙,res = step1 + step2(這里的step1和step2分別表示跳到上一個臺階和跳到上上一個臺階的跳法)巢掺。

public class Solution {
    public int JumpFloor(int target) {
        if(target == 1)
            return 1;
        if(target == 2)
            return 2;
        int result = 0;
        int step1 = 1, step2 = 1;
        target -= 1;
        while(target-- != 0) {
            result = step1 + step2;
            step1 = step2;
            step2 = result;
        }
        return result;
    }
}

第九題

一只青蛙一次可以跳上1級臺階扯再,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法址遇。

????這道題熄阻,最簡單最快速的方法,就是直接用排列組合去做倔约。把n個臺階分成1部分秃殉、2部分、3...n部分浸剩,c(N,0)+c(N,1)+...+C(N,N) = 2^N钾军。

public class Solution {
    public int JumpFloorII(int target) {
        return (int)Math.pow(2, target-1);
    }
}

第十題

我們可以用21的小矩形橫著或者豎著去覆蓋更大的矩形。請問用n個21的小矩形無重疊地覆蓋一個2*n的大矩形绢要,總共有多少種方法吏恭?

????這道題的思路其實(shí)和第八題非常類似,假設(shè)n=5重罪,我們可以看成n=3和n=4兩種情況樱哼,但是注意:n=3時,剩下2個小矩陣剿配,所以還可以排成2種搅幅,但是有其中一種(豎著排列的)會與n=3時候的重復(fù),所以其實(shí)也只能排一種呼胚。所以我們可以知道:當(dāng) n==1時 res = 1茄唐;當(dāng)n==2時,res=2蝇更,當(dāng)n>2時沪编,res = cnt[n-1] + cnt[n-2]。

public class Solution {
    public int RectCover(int target) {
        if(target == 0)
            return 0;
            
        if(target == 1)
            return 1;
        
        if(target == 2)
            return 2;
        
        return RectCover(target-1) + RectCover(target-2);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末年扩,一起剝皮案震驚了整個濱河市蚁廓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌常遂,老刑警劉巖纳令,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挽荠,死亡現(xiàn)場離奇詭異克胳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)圈匆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門漠另,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人跃赚,你說我怎么就攤上這事笆搓⌒允” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵满败,是天一觀的道長肤频。 經(jīng)常有香客問我,道長算墨,這世上最難降的妖魔是什么宵荒? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮净嘀,結(jié)果婚禮上报咳,老公的妹妹穿的比我還像新娘。我一直安慰自己挖藏,他們只是感情好暑刃,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著膜眠,像睡著了一般岩臣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宵膨,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天婿脸,我揣著相機(jī)與錄音,去河邊找鬼柄驻。 笑死狐树,一個胖子當(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
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贺待,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了零截。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片麸塞。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖涧衙,靈堂內(nèi)的尸體忽然破棺而出哪工,到底是詐尸還是另有隱情奥此,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布雁比,位于F島的核電站稚虎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏偎捎。R本人自食惡果不足惜祥绞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸭限。 院中可真熱鬧蜕径,春花似錦、人聲如沸败京。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赡麦。三九已至朴皆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泛粹,已是汗流浹背遂铡。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晶姊,地道東北人扒接。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像们衙,于是被迫代替她去往敵國和親钾怔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350