一、實現Singleton模式 二、二維數組中的查找:每行從左到右遞增,每列從上到下遞增,輸入一個數,判斷數組中是否存在該數 1 2 8 9 2 4 9 12 4 7 10 13 6 8 11 15 如輸入7: 小於第4列的9,則不可能在第4列;column-- 小於第3列的8,則不可能在第3列;column-- 大於第二列的2,則row++; 始終比較右上角的數,相等則返回。(每次查找都會剔除一行或者一列) 三、替換空格: (移動重複,想辦法減小重複,只移動一次!) 遍歷一遍字符串char[],得知空格數目,就可知道替換後的字符串長度,用雙指針p1 p2來從後往前移動字串 p1在p2的前面,指針同步移動(copy字符過去),可是p1遇到空格,p2就往前2步直到p2趕上p1,空格替換完畢 四、從尾到頭部打印鏈表:(先詢問是否能夠改變鏈表結構) 一、不改變:遍歷鏈表,值入棧,遍歷結束再值出棧 二、改變:用頭插法重建鏈表,再順序遍歷鏈表 五、根據前序和中序重建二叉樹:Java代碼 六、用2個棧實現隊列:Java代碼 七、旋轉數組求最小: 八、求斐波那契數列第n項 遞歸;直接用公式O(1);遞推O(n) 相似雙指針 把已經獲得的數列項保存起來 九、求二進制中的1的個數: 最優解法:(1100&1011=1000 能去掉最右邊的1) intNumber(int n ){ int count=0; while(n){ count++; n=(n-1)&n; } } 常規解法: while(flag){ if(n&flag){ count++; flag=flag<<1; } } 十、數值的整數次方: 要考慮負數(利用正數來求),0,正數 double f(double base,unsigned int e){ if(e==0)return 1; if(e==1)return base; double res=f(base,e>>1); res*=res; if(e&1==1)res*=base; return res; }//細節 十二、打印1-n的大數(轉化爲字符) 1三、刪除節點O(1) 值覆蓋p.data=p.next.data;p.next=p.next.next; 1四、調整數組使得奇數位於偶數前面(雙指針一前一後 判斷奇數p&1==1?) 1五、鏈表中的倒數第k個節點(雙指針 注意邊界) 1六、反轉鏈表 (1)雙指針 頭插法(2)三個指針pPrev pNode pNext 直接反轉鏈表 1七、合併2個排序的鏈表: ListNode* Merge(ListNode* pHead1,ListNode* pHead2){ if(pHead1==null)return pHead2; else if (pHead2==null)return pHead1; ListNode* pMergedHead=null; if(pHead1->Value<pHead2->Value){ pMergeHead=pHead1; pMergeHead->next=Merge(pHead->next,pHead2); } else { pMergeHead=pHead2; pMergeHead->next=Merge(pHead1,pHead->next); } return pMergeHead; } 1八、判斷樹B是不是樹A的子結構 struct BinaryTree{ int Value; BinaryTree* left; BinaryTree* right; }; bool HasSubtee(BinaryTreeNode* pRoot1,BinaryTree* pRoot2){ bool result==false; if(pRoot1!=null&&pRoot2!=null){ result=DoesTree1HaveTree2(pRoot1,pRoot2); if(!result) result=HasSubutree(pRoot1->left,pRoot2); if(!result) result=HasSubtree(pRoot1->right,pRoot2); } return result; } bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1,BinaryTreeNode* pRoot2){ if(pRoot2==null)return true; if(pRoot1==null)return false; if(pRoot1->Value!=pRoot2->Value)return false; return DoesTree1HaveTree2(pRoot1->left,pRoot->left)&&DoesTree1HaveTree2(pRoot1- >right,pRoot2->right); } 1九、二叉樹的鏡像: void MirrorRecursively(BinaryTreeNode* pNode){ if((pNode==null)||(pNode->left==null&&pNode->right))return; //先寫遞歸代碼,再添加退出條件 BinaryTreeNode* pTemp=pNode->left; pNode->left=pNode->right; pNode-right=pTemp; if(pNode->left)MirrorRecursively(pNode->left); if(pNode-right)MirrorRecursively(pNode-right); } 20、順時針打印矩陣 2一、包含min函數的棧 2個棧,一個數據棧,一個輔助棧,輔助棧中棧頂始終數據棧的最小元素,若進棧元素大於最小值,則重複加 入 最小值到輔助棧中,由於它是當前最小,若小於最小值,則加入該最小值到輔助棧中(2個棧元素數量始終一致) 2二、棧的壓入彈出序列(判斷第二個序列是不是第一個序列的彈出序列) 若是第二個序列中當前要判斷的元素恰好與棧頂元素相等,則直接pop出來,若是不等,則將第一個序列的 後面尚未入棧的元素入棧,直到將與之相等的元素入棧爲止,若是第一個序列的全部的元素都入棧了,尚未 找到與之相等的元素,則說明第二個序列不是第一個序列的彈出序列 2三、從上往下打印二叉樹 隊列,逐層遍歷 2四、二叉搜索樹的後續遍歷序列 2五、二叉樹中和爲某一值的路徑: 棧 先序遍歷 2六、複雜鏈表的複製: (1)A->A'->B->B'...(另外一指針A->B) (2)關鍵是A'->other=A->other-next; (3)鏈表拆分 獲得copy的鏈表 2七、二叉搜索樹與雙向鏈表 (空) 2八、字符串的排列:全排列 2九、求數組中出現超過一半的數 (1)基於partition函數的O(n)算法,同快排的partition。會改變數組中數字的位置 (2)在遍歷數組的時候,保存2個數字,一個是數組中的數,一個是次數,遍歷到下一個數字時,若是和記 錄的數字相等,次數+1;若是不一樣則次數-1;若是次數爲0,則保存下一個數字,次數置爲1。O(n) 30、最小的k個數 (1)partition函數劃分,O(n) (2)用最大堆做爲裝這k個數的容器(也能夠用紅黑樹這種數據結構),每次取出最大的數,遍歷完n個數 後,獲得最小的k個數。O(logk) (能夠先判斷k>n/2則求前n-k大) 3一、求連續子數組的最大和 動態規劃 3二、從1到n整數中1出現的次數???? 3三、把數組排成最小的數(用字符串表示數字,解決大數問題??) 3四、醜數? (1)逐個判斷該整數是否是醜數 (2)建立數組保存已經找到的醜數??? 3五、第一次只出現一次的字符: (1)掃描一遍字符串 int a[26]; a[字符-'a']++ hash的思想 (2)再次掃描字符串 輸出第一個知足 a[字符-'a']==1的字符 3六、數組中的逆序對:在數組中的2個數字若是前面一個數字大於後面的數字,則這2個數字組成一個逆序對 (1)暴力解法O(n^2){7 6 5}中有(7,6)(7,5)(6,5) (2)歸併的思想??O(nlogn) 3七、2個鏈表的第一個公共子節點 最高效的解法:遍歷鏈表獲得長度m n 大的減少的=a,雙指針 長的先走a步,再一塊兒走,逐個判斷節點 是不是同一個。O(m+n) 3八、數字在排序數組中出現的順序,二分法O(logn) 通常解法O(n) 3九、求二叉樹的深度 遞歸代碼最簡 拓展:判斷一棵樹是不是平衡樹(任一節點的左右子樹的高度差不大於1)後序遍歷每一個節點只訪問一次? 40、數組中只出現一次的數字(有2個這樣的數):要求時間O(n) 空間O(1) (異或:相同數字異或爲0,任一數異或0爲自己) 倘若數組中只有一個數只出現一次,數組中數字逐個異或的結果就是隻出現一次的數字; 如今就要想辦法,把這2個只出現一次的數分到2個子數組中,就能獲得結果。 4異或6=100異或110=010 差異就是在第二個bit位上,因此咱們能夠把全部數字按這個原則分紅2組 4和6必定會被分到不一樣的組中,相同的數字會被分到同一組中。 4一、一個遞增排序的數組和一個數s,在數組中查找2個數的和正好是s,輸出任一對便可 通常解法是暴力O(n^2) 雙指針-首尾指針的解法是O(n) 拓展:打印和爲s的連續正數序列 15=1+2+3+4+5=4+5+6=7+8 打印(1 2 3 4 5)(4 5 6)(7 8 ) 先造成清晰的解題思路,才能開始寫代碼;藉助上題雙指針的思路 最開始:small big 指向1 2 和爲3<9 big增大 123 和爲6<9 增大big 1234 10>9 增大small 2 3 4 =9 打印 再增大big 2 3 4 5 和14>9 減少small。。。找到4 5 =9 (循環退出條件:small<middle)其中middle=(1+sum)/2; 4二、翻轉字符串"I am a student."->"student. a am I" 2次翻轉 先整個reverse再單個單詞reverse 拓展:左旋字符串:輸入abcde 2 輸出cdeab 先ab->ba cde-> edc 即abcde->baedc baedc再reverse獲得cdeab(注意邊界 null) 4三、n個色子的點數? 4四、撲克牌的順子? 4五、圓圈中剩下的數字: 題目:0 1 2 3 ...n-1這n個數字排成一圈,從0開始每次從這個圓圈中刪除第m個數字,求這個圓圈最後剩 下哪一個數字? 有名的約瑟夫環問題 4六、?求1+2+3+...+n要求不能乘除法、for while if else swith case 條件判斷語句 4七、不用加減乘除作加法 4八、不能被繼承的類 java中用final C++中沒有,能夠把構造函數設爲私有 4九、字符串轉換爲整數(本身想好特殊的測試用例) 50、樹中2個結點的最低公共祖先(問清楚需求,也許對方是故意漏掉條件考你的思路)