一、实现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个结点的最低公共祖先(问清楚需求,也许对方是故意漏掉条件考你的思路)