GitHub#algorithm#:《劍指offer》 的50道面試題
- Copyright(C) nonstriater:https://github.com/nonstriater/Learn-Algorithms
《劍指offer》 這本書給出了50到面試題,涉及到字串處理,堆疊,連結串列,二叉樹等問題的處理。
- 程式碼魯榜性:邊界條件,特殊輸入,異常處理:空指標
- 分析方法:畫圖,舉例,分解
- 查詢和排序是常考:重點掌握二分查詢,快速排序,歸併排序
- 本書完整原始碼在:
賦值運算子函式
實現Singleton模式
二維陣列中的查詢
二維陣列中每一行從左到右遞增,每一列從上到下遞增,判斷陣列中是否包含該整數。
bool find(int *matrix,int rows,int columns,int numbers)
替換空格
如把字串中的每個空格替換成%20
二遍掃描
void replace_blank(char *str);
從尾到頭列印連結串列
棧
void print_reversing(LinkList *head)
重建二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,重建該二叉樹
BinaryTree *construct(int *preorder,int inroder,int length);
用兩個棧實現佇列
佇列就是在尾部插入節點,頭部刪除節點。
旋轉陣列的最小數字
旋轉陣列是指把一個陣列最開始的若干個元素搬到陣列的末尾。輸入一個遞增排序的陣列的旋轉,比如{3,4,5,1,2}是{1,2,3,4,5}的一個旋轉。求該陣列的最小值。
int min(int *num, int length)
菲波那切數列
long long fabonacci(unsigned n)
二進位制中1的個數
輸入一個整數,輸出該數二進位制中1出現的次數。比如9的二進位制 10001,輸出是2
n=n&n-1
int one_appear_count(int n)
數值的整數次方
要求不得使用庫函式。這裡注意考慮指數是0和負數的情況
double power(double base,int exponent)
列印1到最大的n位數
比如n=3,就列印1到999
void print_to_max_with_length(int n)
在O(1)時間刪除連結串列節點
已經有一個頭節點指標,還有一個指向改刪除節點的指標
用下一個節點的內容覆蓋當前刪除節點的內容,刪除下一個節點
void deleteNode(LinkList *head,LinkList *targetToDelete);
調整陣列順序使奇數位於偶數前面
調整後,所有奇數在前半部分,偶數在後半部分
兩邊向中間掃描
void reorder(int *data,int length)
輸出連結串列中倒數第K個節點
使用兩個指標,一個先走k-1步
void print_lastK(LinkList *head);
反轉連結串列
三個指標
void reverse(LinkList *head);
反轉二叉樹呢?
合併2個排序的連結串列
要求合併以後連結串列任然排序
遞迴
LinkList *merge(LinkList *one,LinkList *two);
樹的子結構
考察二叉樹的基本操作。輸入2課二叉樹A和B,判斷B是不是A的子結構。
struct BinaryTreeNode{
int m_value;
BinaryTreeNode *m_pleft;
BinaryTreeNode *m_pRight;
}
8
/ \ 10
/ \ / \
6 10 子結構 11 9
/ \ / \
5 7 9 11
bool subTree(BinaryTreeNode *root1,BinaryTreeNode *root2);
二叉樹翻轉
8 8
/ \ / \
/ \ / \
6 10 翻轉後 10 6
/ \ / \ / \ / \
5 7 9 11 11 9 7 5
交換每個節點的左右子樹
void reverse(BinaryTreeNode *root);
從外向裡順時針列印矩陣
void print_matrix_clockwise(int *matrix,int cols,int rows);
延伸:按大小順序列印矩陣
實現一個能找到棧的最小元素的函式
最小元素用輔助棧儲存
int min(Stack *stack)
棧的壓入,彈出序列
輸入2個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否為該棧的彈出順序。比如:
1,2,3,4,5是壓棧序列,4,5,3,2,1是彈棧序列,但是4,3,5,1,2就不是彈棧序列
bool is_pop_order(int *push,int *pop,int length)
從上往下列印二叉樹
輔助佇列
void print_binary_level(BinaryTreeNode *root)
二叉搜尋樹的後續遍歷序列
輸入一個整數陣列,判斷該陣列是不是某二叉查詢樹的後續遍歷序列的結果。比如【 5,7,6,9,11,10,8】 是下面二叉查詢樹的後續遍歷結果:
8
/ \
/ \
6 10
/ \ / \
5 7 9 11
尋找規律
bool is_post_order(BST *root,int *data, int length);
二叉樹中和為某一值的路徑
10
/ \
/ \
5 12
/ \
5 7
和為22的路徑有2條:10--5--7, 10--12
遞迴,棧
void print_path(BinaryTree *root,int n)
複雜連結串列的複製
在複雜連結串列結構中,每個節點都有一個指向下一個節點的m_pNext;還有一個指向任意節點的m_pSibling
typedef struct LinkListNode{
int m_value;
LinkListNode *m_pNext;
LinkListNode *m_pSlbling;
}LinkList;
LinkList * copy(LinkList *head);
二叉搜尋樹與雙向連結串列
將二叉搜尋樹轉換成一個排序的雙向連結串列,只調整樹中節點的指標指向
遞迴
分解問題
BST *transform(BST *root);
字串的排列
輸入一個字串,列印該字串中字元的所有排列
遞迴,分解
void print_full_permutation(char *string)
陣列中出現次數超過一半的數字
遍歷陣列,下一個數字和之前儲存的數字一樣就+1,否則就-1
int find_more_than_half_num(int *nums ,int length)
n個整數中最小的K個數
快速排序
最大堆
void find_least_k(int *data,int n,int *ouput,int k)
最大的K個數呢?
連續子陣列的最大和
輸入一個整數陣列,有正有負,求所有子陣列的和的最大值
分析規律
動態規劃
int max_of_subarray(int *data,int length)
從1到n整數中,1出現的次數
比如 12,從1到12這些整數中,包含1的數字有 1, 10,11,12 ,1出現了5次
int one_appear_count(int n)
把陣列排成最小的數
輸入一個正整數陣列,把所有數字拼起來排出一個最小數
int minSort(int *nums, int length);
醜數
只包含因子 2,3,5的數叫做醜數
求按從小到大的順序,第1500個醜數
int ugly(int n)
第一個只出現一次的字元
在字串中查詢第一個只出現一次的字元
雜湊表:值為出現的次數
二次掃描
char find_appear_once_char(char *string)
陣列中的逆序對
陣列中的兩個數字如果前面一個數字大於後面的數字,這兩個數字組成一個逆序對。如:[7,5,6,4] 的逆序對:(7,5)(7,6)(7,4)(5,4)(6,4)
輸入一個陣列,求出這個陣列逆序對總數。
歸併排序 O(nlogn),空間O(n)
int reversePairs(int *data,int length)
兩個連結串列的第一個公共節點
長的連結串列先走k步
LinkListNode *common_node(LinkList *head1,LinkList head2);
數字在排序陣列中出現的次數
比如 {1,2,3,3,3,3,4,5}, 數字 3出現了4次
使用二分查詢找第一個3,和最後一個3出現的位置
int appear_count(int *nums,int length,int n);
二叉樹的深度
遞迴
int tree_depth(BTree *root);
陣列中只出現一次的數字
陣列中除了2個數字之外,其他的陣列都出現了2次,找出這兩個數
異或
二進位制
如果是隻有1個數字只出現一次,我們可以通過對陣列依次做異或運算。
如果我們能把原陣列分成2個子陣列,每個子陣列都包含一個只出現一次的數字,問題就能解決了。我們把陣列中的所有數字依次做異或操作,如果有2個數字不一樣,結果肯定不是0,且異或結果數字的二進位制表示中至少有一位是1(不然結果不就是0了)
- 在結果數字二進位制表示中找到第一個為1的位的位置,標記n
- 以二進位制表示中第n位是不是1為標準,把原陣列分成2個子陣列
void find_two_numbers_appear_once(int *data,int length,int *ouput)
和為s的兩個數字 VS 和為s的連續正數序列
有一個遞增排序陣列,和一個數字s,找出陣列中的2個數,使得和等於s。輸出任意一對即可
兩邊向中間掃描
void print_two_numbers(int *data,int length,int sum)
反轉單詞順序 VS 左旋轉字串
a. 翻轉句子中單詞的順序,但單詞內字元不變。如 『I am a student』 -> 『student. a am I』
先以單詞為單位翻轉,整個句子再次翻轉
char *reverse_by_word(char *string)
b. 左旋轉字串是把字串其那面的若干位轉義到字串的尾部。比如"abcedfsz"和數字2,結果是"cedfszab"
char *left_rotate_string(char *s,int n)
n個色子的點數
把n個色子丟地上,朝上一面的點數之和為s。輸入n,列印可能的值出現的概率
void print_sum_probability(int n)
撲克牌中的順子
從撲克牌從隨機抽5張牌,判斷是不是順子。A是1,JK是1113,大小王可以看出任意數字。
bool is_straight(int *data,int length)
圓圈中最後剩下的數字(約瑟夫問題)
0,1,...,n-1 這n個數字排成一個圓圈,從數字0開始從這個圓圈裡面刪除第m個數字,求出這個圓圈裡最後剩下的數字。
int last_remaining(unsigned int n,unsigned int m)
求 1+2+...+n
要求不用乘除法,for/while/if/else/switch等關鍵字及條件判斷語句
long long sum(unsigned int n);
不用加減乘除做加法
求2個整數之和
位運算
int sum(int,int)
不能被繼承的類
把字串轉換成整數
比如 "12343567754" -> 12343567754
NULL,空串,正負號,溢位
int strToInt(char str);
樹中2個結點的最低公共祖先
如果這個樹是二叉排序樹
如果不是二叉排序樹,但是有父節點指標
如果不是二叉樹,也沒有父節點指標
相關文章
- 「劍指offer」27道Mybatis面試題含解析MyBatis面試題
- 劍指offer面試題(41-50)——java實現面試題Java
- 劍指offer中幾道演算法題的思考演算法
- 劍指offer面試題11 數值的整數次方面試題
- 劍指Offer題解合集
- 劍指offer面試題29:順時針列印矩陣面試題矩陣
- 劍指offer 面試題47:不用加減乘除做加法面試題
- 劍指offer面試18 樹的子結構面試
- 劍指offer刷題記錄
- 劍指offer面試題12 列印1到最大的n位數面試題
- 劍指Offer--面試題1:賦值運算子函式面試題賦值函式
- 劍指offer面試16 反轉連結串列面試
- 【劍指offer】字串的排列字串
- 最全的50道Redis面試題Redis面試題
- 劍指Offer——面試小提示(持續更新中)面試
- 【劍指offer】【2】字串的空格字串
- 【劍指offer】字串的組合字串
- [劍指Offer]面試題35:第一個只出現一次的字元面試題字元
- 劍指Offer系列刷題筆記彙總筆記
- 【劍指offer】讓抽象問題具體化抽象
- 劍指Offer面試題5(Java版):從尾到頭列印連結串列面試題Java
- 劍指offer-JavaScript版JavaScript
- 【劍指offer】左旋轉字串字串
- 劍指offer面試17 合併兩個排序的連結串列面試排序
- 劍指 Offer 38. 字串的排列字串
- 劍指Offer 表示數值的字串字串
- 【劍指offer】樹的子結構
- 劍指offer面試題15 連結串列中倒數第K個結點面試題
- 《劍指offer》JAVA題解,LeetCode評測JavaLeetCode
- LeetCode-劍指Offer刷題記錄LeetCode
- 劍指offer面試題9 斐波那契數列及青蛙跳臺階問題面試題
- 阿里面試最最俱全的,50道Redis面試題阿里Redis面試題
- 劍指offer-Go版實現 第四章:解決面試題的思路Go面試題
- 劍指offer面試題12:矩陣中的路徑(Java版已在牛客網AC)面試題矩陣Java
- 劍指offer 面試題 7 :二叉樹的下一個節點是什麼?面試題二叉樹
- 劍指 offer(1) -- 陣列篇陣列
- Leetcode劍指offer(八)LeetCode
- 【劍指offer】字串轉整數字串