題目來源:牛客網
題目一 復雜鏈表的復制
描述:
輸入一個復雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點)。
解題思路: 代碼
題目二 字符串的排列
描述:
輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。 結果請按字母順序輸出。
解題思路: 代碼
以abc為例:
- 固定a,將后面的bc進行排列,有兩種排列方法:bc,cb;
- 固定b,將后面的ac進行排列,有兩種排列方法:ac,ca;
- 股東c,將后面的ab進行排列,有兩種排列方法:ab,ba;
- 輸出,abc,acb,bac,bca,cab,cba;
題目三 數組中出現次數超過一半的數字
描述:
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度為9的數組{1,2,3,2,2,2,5,4,2}。由于數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。
解題思路: 代碼
- 如果數組中某數字出現的次數超過數組長度的一半,那么在排序后,該數一定在數組的中間;
- 先進行快排,然后取數組最中間的數;
- 遍歷該數組,如果最中間的數出現的次數超過數組長度的一半,則輸出這個數;
題目四 最小的K個數
描述:
輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
解題思路: 代碼
解法一:
- 將數組進行快排;
- 取快排后前K個數;
解法二: - 將數組前k個數放到一個copy到一個數組int[] temp中;
- 將temp數組快排;
- 取從原數組第k個元素開始,逐個與temp數組中最大的元素temp[k-1]進行比較;
- 如果temp[k-1]比原數組小,則原數組取下一個,如果temp[k-1],大于原數組中元素,則兩個數進行交換,temp數組快排;
- 最后輸出temp數組;
題目五 連續子數組的最大和
描述:
HZ偶爾會拿些專業問題來忽悠那些非計算機專業的同學。今天測試組開完會后,他又發話了:在古老的一維模式識別中,常常需要計算連續子向量的最大和,當向量全為正數的時候,問題很好解決。但是,如果向量中包含負數,是否應該包含某個負數,并期望旁邊的正數會彌補它呢?例如:{6,-3,-2,7,-15,1,2,2},連續子向量的最大和為8(從第0個開始,到第3個為止)。你會不會被他忽悠住?
解題思路: 代碼
使用動態規劃的思想:
- 令currSum是以當前元素結尾的最大連續子數組的和;
- maxSum是全局的最大子數組的和;
- 當往后掃描時:對第j個元素有兩種選擇,要么放入前面找到的子數組,要么最為新的子數組的第一個元素;
- 如果currSum > 0,則令currSum加上a[j];
- 如果currSum < 0,則currSum被置為當前元素;即currSum = a[j];
舉例:{1,-2,3,10,-4,7,2,-5};
currSum: 0 -> 1 -> -1 -> 3 -> 13 -> 9 -> 16 ->18 -> 13;
maxSum: 0 -> 1 -> 1 -> 3 -> 13 -> 13 -> 16 -> 18 -> 18;
題目六 整數中1出現的次數(從1到n整數中1出現的次數)
描述:
求出113的整數中1出現的次數,并算出1001300的整數中1出現的次數?為此他特別數了一下1~13中包含1的數字有1、10、11、12、13因此共出現6次,但是對于后面問題他就沒轍了。ACMer希望你們幫幫他,并把問題更加普遍化,可以很快的求出任意非負整數區間中1出現的次數。
解題思路: 代碼
*這是一個數學問題的算法,代碼很容易,但是不懂這個數學問題為什么會是這樣?
題目七 把數組排成最小的數
描述:
輸入一個正整數數組,把數組里所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字為321323。
解題思路: 代碼
該題目考察的就是對給出的數組進行排序; 以數組{3,32,321}為例:
"3"與"32"不能直接進行"3".compareTo("32")的運算;而是將兩個字符串拼接后進行再進行比較,如:"332".compareTo("323");否則使用該函數的時候首先要對字符串的長度進行比較;得到排序后的數組{"321","32","3"},將三個字符串按照順序進行拼接后即可得到最小字符串;
題目八 第一個只出現一次的字符位置
描述:
在一個字符串(1<=字符串長度<=10000,全部由字母組成)中找到第一個只出現一次的字符的位置。若為空串,返回-1。位置索引從0開始
解題思路: 代碼
- 使用HashMap<Character,Integer>將字符串中的字符存起來,有重復字符則在hashmap的value加1;
- 存進hashmap后,依次遍歷String字符串中的每一個字符,找到第一個value為1的char的索引值;
題目九 數組中的逆序對
描述:
在數組中的兩個數字,如果前面一個數字大于后面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個數組中的逆序對的總數。解題思路: 代碼
使用冒泡排序的思想,使用兩個for循環;(這個不是最優的解法,希望可以找到更好的算法)
題目十 兩個鏈表的第一個公共結點
描述:
輸入兩個鏈表,找出它們的第一個公共結點。
解題思路: 代碼
將第一個鏈表的節點存到hashmap中,然后第二個節點依次取出節點在hashmap中查找公共節點;
題目十一 數字在排序數組中出現的次數
描述:
統計一個數字在排序數組中出現的次數。
解題思路: 代碼
- 解法一:直接遍歷數組查找;
- 解法二:使用二分法的思想,找出這個數第一次出現的位置和最后一次出現的位置,然后計算出次數;
題目十二 二叉樹的深度
描述:
輸入一棵二叉樹,求該樹的深度。從根結點到葉結點依次經過的結點(含根、葉結點)形成樹的一條路徑,最長路徑的長度為樹的深度。
解題思路: 代碼
使用遞歸的思想:取左子樹與右子樹深度較大的;
題目十三 平衡二叉樹
描述: 輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。
解題思路: 代碼
該題目的實質就是遞歸求二叉樹左右子樹的深度;
劍指Offer筆試題(4)
以上代碼全部托管在 Github