剑指offer学习--实现单例模式】的更多相关文章

只能生成一个实例的类是为了实现单例模式的类型. 加同步锁前后两次判断实例是否已存在 我们只是在实例还没有创建之前加锁操作,以保证只有一个线程创建出实例.而当实例已经创建之后,我们已经不需要再做加锁操作了. public sealed class Singleton { private Singelton() { } private static object syncObj = new object(); private static Singleton instance = null; pub…
剑指Offer学习 剑指Offer这本书已经学习完了.从中也学习到了不少的东西,如今做一个总的文件夹.供自已和大家一起參考.学如逆水行舟.不进则退.仅仅有不断地学习才干跟上时候.跟得上技术的潮流! 全部代码下载[https://github.com/Wang-Jun-Chao/coding-interviews] 文件夹 第01-10题 [剑指Offer学习][面试题02:实现Singleton 模式--七种实现方式] [剑指Offer学习][面试题03:二维数组中的查找] [剑指Offer学习…
剑指Offer学习 剑指Offer这本书已经学习完了,从中也学习到了不少的东西,现在做一个总的目录,供自已和大家一起参考,学如逆水行舟,不进则退.只有不断地学习才能跟上时候,跟得上技术的潮流! 所有代码下载[https://github.com/Wang-Jun-Chao/coding-interviews] 目录 第01-10题 [剑指Offer学习][面试题02:实现Singleton 模式——七种实现方式] [剑指Offer学习][面试题03:二维数组中的查找] [剑指Offer学习][面…
最近一直看剑指Offer.里面很多算法题.于是就想着用PHP来显示一下. 题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. 请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 拿到这个题目.我们第一个反应,就是遍历二维数组.然后逐个进行比较.我们不难用PHP进行实现.于是有了下面的代码 function TwoArrayFind($array,$search) { $found = false; if(empty($ar…
第 1 天 栈与队列(简单) 剑指 Offer 09. 用两个栈实现队列 class CQueue { public: CQueue() { } stack<int>s1,s2; void appendTail(int value) { s1.push(value); } int deleteHead() { if(s2.empty()) { while(!s1.empty()) { s2.push(s1.top()); s1.pop(); } } if(s2.empty()) return…
题目:请实现一个函数用来找出字符流中第一个仅仅出现一次的字符. 举例说明 比如,当从字符流中仅仅读出前两个字符"go"时.第一个仅仅出现一次的字符是'g'.当从该字符流中读出前六个字符"google"时,第一个仅仅出现1次的字符是"l". 解题思路 字符仅仅能一个接着一个从字符流中读出来.能够定义一个数据容器来保存字符在字符流中的位置.当一个字符第一次从字符流中读出来时,把它在字符流中的位置保存到数据容器里.当这个字符再次从字符流中被读出来时.那…
题目:请完毕一个函数,输入一个二叉树,该函数输出它的镜像. 二叉树结点的定义: /** * 二叉树的树结点 */ public static class BinaryTreeNode { int value; BinaryTreeNode left; BinaryTreeNode right; } 解题思路: 我们先前序遍历这棵树的每一个结点.假设遍历到的结点有子结点.就交换它的两个子结点.当交换全然部非叶子结点的左右子结点之后.就得到了树的镜像. 代码实现: public class Test…
题目:一个整型数组里除了两个数字之外.其它的数字都出现了两次,请敲代码找出这两个仅仅出现一次的数字. 要求时间复杂度是O(n),空间复杂度是O(1). 举例说明 比如输入数组{2, 4, 3, 6, 3, 2, 5 },由于仅仅有4 .6 这两个数字仅仅出现一次,其它数字都出现了两次,所以输出4和6 . 解题思路 这两个题目都在强调一个(或两个)数字仅仅出现一次,其它的出现两次. 这有什么意义呢?我们想到异或运算的一个性质:不论什么一个数字异或它自己都等于0.也就是说. 假设我们从头到尾依次异或…
题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序.使得全部奇数位于数组的前半部分.全部偶数位予数组的后半部分. 这个题目要求把奇数放在数组的前半部分, 偶数放在数组的后半部分,因此全部的奇数应该位于偶数的前面.也就是说我们在扫描这个数组的时候, 假设发现有偶数出如今奇数的前面.我们能够交换它们的顺序,交换之后就符合要求了. 因此我们能够维护两个指针,第一个指针初始化时指向数组的第一个数字,它仅仅向后移动:第二个指针初始化时指向数组的最后一个数字, 它仅仅向前移动. 在两个指针相遇之前…
题目:把n个骰子扔在地上,全部骰子朝上一面的点数之和为s.输入n.打印出s 的全部可能的值出现的概率. 解题思路 解法一:基于通归求解,时间效率不够高. 先把n个骰子分为两堆:第一堆仅仅有一个.还有一个有n- 1 个.单独的那一个有可能出现从1 到6 的点数. 我们须要计算从1 到6 的每一种点数和剩下的n-1 个骰子来计算点数和.接下来把剩下的n-1个骰子还是分成两堆,第一堆仅仅有一个, 第二堆有n-2 个.我们把上一轮那个单独骰子的点数和这一轮单独骰子的点数相加. 再和剩下的n-2 个骰子来…
题目:一个链表中包括环.怎样找出环的入口结点? 解题思路 能够用两个指针来解决问题.先定义两个指针P1和P2指向链表的头结点.假设链表中环有n个结点,指针P1在链表上向前移动n步,然后两个指针以同样的速度向前移动. 当第二个指针指向环的入口结点时,第一个指针已经环绕着环走了一圈又回到了入口结点. 剩下的问题就是怎样得到环中结点的数目.我们在面试题15的第二个相关题目时用到了一快一慢的两个指针. 假设两个指针相遇,表明链表中存在环.两个指针相遇的结点一定是在环中. 能够从这个结点出发.一边继续向前…
题目:从上到下按层打印二叉树,同一层的结点按从左到右的顺序打印,每一层打印一行. 解题思路 用一个队列来保存将要打印的结点.为了把二叉树的每一行单独打印到一行里,我们须要两个变量:一个变量表示在当前的层中还没有打印的结点数,还有一个变量表示下一次结点的数目. 结点定义 private static class BinaryTreeNode { private int val; private BinaryTreeNode left; private BinaryTreeNode right; p…
题目:在数组中的两个数字假设前面一个数字大于后面的数字.则这两个数字组成一个逆序对.输入一个数组.求出这个数组中的逆序对的总数. 举例分析 比如在数组{7, 5, 6, 4 中, 一共存在5 个逆序对,各自是(7, 6).(7.5),(7, 4).(6, 4)和(5, 4). 解题思路: 第一种:直接求解 顺序扫描整个数组. 每扫描到一个数字的时候,逐个比較该数字和它后面的数字的大小.假设后面的数字比它小.则这两个数字就组成了一个逆序对.假设数组中含有n 个数字.因为每个数字都要和O(n)个数字…
题目:输入两棵二叉树A 和B.推断B 是不是A 的子结构. 二叉树结点的定义: /** * 二叉树的树结点 */ public static class BinaryTreeNode { int value; BinaryTreeNode left; BinaryTreeNode right; } 解题思路: 要查找树A 中是否存在和树B 结构一样的子树.我们能够分成两步: 第一步在树A 中找到和B 的根结点的值一样的结点R. 第二步再推断树A 中以R 为根结点的子树是不是包括和树B 一样的结构…
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是依照递增排序的 链表结点定义例如以下: public static class ListNode { int value; ListNode next; } 解题思路: 见代码凝视 代码实现: public class Test17 { public static class ListNode { int value; ListNode next; } /** * 输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是依…
接着上面一篇文章: http://blog.csdn.net/u013476464/article/details/40651451 接下来我们拓展一下题目,如果数组是乱序的,并且规定数组中的元素所有为非负整数,相同给定一个数sum,在数组中找出随意两个数,使二者的和为sum. 分析: 由于题目中限定了数组中的元素为非负整数,因此我们能够用哈希数组,开辟一个长度为sum的bool数组B[sum],并所有初始化为false,对数组A进行一次遍历,假设当前的元素A[i]大于sum,则直接跳过,否则,…
题目: 定义栈的数据结构,请在该类型中实现一个可以得到栈的最小素的min 函数.在该栈中.调用min.push 及pop的时间复杂度都是0(1) 解题思路: 把每次的最小元素(之前的最小元素和新压入战的元素两者的较小值)都保存起来放到另外一个辅助栈里 假设每次都把最小元素压入辅助栈, 那么就能保证辅助栈的栈顶一直都是最小元素.当最小元素从数据栈内被弹出之后,同一时候弹出辅助栈的栈顶元素,此时辅助栈的新栈顶元素就是下一个最小值. 代码实现: public class Test21 { /** *…
题目:求树中两个结点的最低公共祖先,此树不是二叉树,而且没有指向父节点的指针. 树的结点定义 private static class TreeNode { int val; List<TreeNode> children = new LinkedList<>(); public TreeNode() { } public TreeNode(int val) { this.val = val; } @Override public String toString() { retur…
题目:从上往下打印出二叉树的每一个结点,同一层的结点依照从左向右的顺序打印. 二叉树结点的定义: public static class BinaryTreeNode { int value; BinaryTreeNode left; BinaryTreeNode right; } 解题思路: 这道题实质是考查树的遍历算法.从上到下打印二叉树的规律:每一次打印一个结点的时候,假设该结点有子结点, 则把该结点的子结点放到一个队列的末尾.接下来到队列的头部取出最早进入队列的结点,反复前面的打印操作,…
package 二维数组查找; public class Test03 { /** * 在一个二维数组中,每一行都按 package 二维数组查找; public class Test03 { /** * 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序. * 请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. * <p/> * 规律:首先选取数组中右上角的数字.如果该数字等于要查找的数字,查找过程结束: * 如果该数字大于要查…
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请推断二个序列是否为该栈的弹出顺序.假设压入栈的全部数字均不相等. 解题思路: 解决问题非常直观的想法就是建立一个辅助栈.把输入的第一个序列中的数字依次压入该辅助栈.并依照第二个序列的顺序依次从该栈中弹出数字. 推断一个序列是不是栈的弹出序列的规律:假设下一个弹出的数字刚好是栈顶数字,那么直接弹出.假设下一个弹出的数字不在栈顶,我们把压栈序列中还没有入栈的数字压入辅助栈,直到把下一个须要弹出的数字压入栈顶为止.假设全部的数字都压入栈了仍然没有找…
题目:输入两个链表,找出它们的第一个公共结点. 链表结点定义 /** * 链表结点类 */ private static class ListNode { int val; ListNode next; public ListNode() { } public ListNode(int val) { this.val = val; } @Override public String toString() { return val + ""; } } 解题思路: 第一种:直接法 在第一个…
题目:给定一棵二叉树和当中的一个结点.怎样找出中序遍历顺序的下一个结点?树中的结点除了有两个分别指向左右子结点的指针以外,另一个指向父节点的指针. 解题思路 假设一个结点有右子树.那么它的下一个结点就是它的右子树中的左子结点.也就是说右子结点出发一直沿着指向左子结点的指针.我们就能找到它的下一个结点. 接着我们分析一个结点没有右子树的情形. 假设结点是它父节点的左子结点.那么它的下一个结点就是它的父结点. 假设一个结点既没有右子树.而且它还是它父结点的右子结点.这种情形就比較复杂.我们能够沿着指…
题目:输入一个正整数数组,把数组里全部数字拼接起来排成一个数.打印能拼接出的全部数字中最小的一个. 样例说明: 比如输入数组{3. 32, 321},则扫描输出这3 个数字能排成的最小数字321323. 解题思路: 第一种:直观解法 先求出这个数组中全部数字的全排列,然后把每一个排列拼起来,最后求出拼起来的数字的最大值. 另外一种:排序解法 找到一个排序规则,数组依据这个规则排序之后能排成一个最小的数字.要确定排序规则,就要比較两个数字,也就是给出两个数字m 和n,我们须要确定一个规则推断m 和…
题目:请实现两个函数,分别用来序列化和反序列化二叉树. 解题思路 通过分析解决前面的面试题6.我们知道能够从前序遍历和中序遍历构造出一棵二叉树.受此启示.我们能够先把一棵二叉树序列化成一个前序遍历序列和一个中序序列.然后再反序列化时通过这两个序列重构出原二叉树. 这个思路有两个缺点.一个缺点是该方法要求二叉树中不能用有数值反复的结点. 另外仅仅有当两个序列中全部数据都读出后才干開始反序列化. 假设两个遍历序列的数据是从一个流里读出来的,那就可能须要等较长的时间. 实际上假设二叉树的序列化是从根结…
题目:请设计一个函数,用来推断在一个矩阵中是否存在一条包括某字符串全部字符的路径.路径能够从矩阵中随意一格開始.每一步能够在矩阵中间向左.右.上.下移动一格.假设一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子. 举例分析 比如在以下的3*4的矩阵中包括一条字符串"bcced"的路径. 但矩阵中不包括字符串"abcb"的路径,因为字符串的第一个字符b占领了矩阵中的第一行第二格子之后,路径不能再次进入这个格子. a b c e s f c s a d e e…
题目:给定一个数组和滑动窗体的大小,请找出全部滑动窗体里的最大值. 举例说明 比如,假设输入数组{2,3,4,2,6,2,5,1}及滑动窗体的大小.那么一共存在6个滑动窗体,它们的最大值分别为{4,4,6,6,6,5}. 解题思路 假设採用蛮力法,这个问题似乎不难解决:能够扫描每个滑动窗体的全部数字并找出当中的最大值.假设滑动窗体的大小为k,须要O(k)时间才干找出滑动窗体里的最大值.对于长度为n的输入数组,这个算法总的时间复杂度是O(nk). 实际上一个滑动窗体能够看成是一个队列.当窗体滑动时…
题目:输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组.求全部子数组的和的最大值.要求时间复杂度为O(n). 样例说明: 比如输入的数组为{1, -2, 3, 10, -4, 7, 2, -5}.和最大的子数组为{3, 10, -4, 7, 2}.因此输出为该子数组的和18 . 解题思路: 解法一:举例分析数组的规律. 我们试着从头到尾逐个累加演示样例数组中的每一个数字. 初始化和为0.第一步加上第一个数字1. 此时和为1. 接下来第二步加上数字-2,和就变成了-…
题目:我们把仅仅包括因子2.3 和5 的数称作丑数(Ugly Number).求从小到大的顺序的第1500个丑数. 举例说明: 比如6.8 都是丑数.但14 不是.它包括因子7.习惯上我们把1 当做第一个丑数. 解题思路: 第一种:逐个推断每个数字是不是丑数的解法,直观但不够高效. 另外一种:创建数组保存已经找到丑数,用空间换时间的解法. 依据丑数的定义. 丑数应该是还有一个丑数乘以2.3 或者5 的结果(1除外). 因此我们能够创建一个数组,里面的数字是排好序的丑数,每个丑数都是前面的丑数乘以…
题目:给定一棵二叉搜索树,请找出当中的第k大的结点. 解题思路 假设依照中序遍历的顺序遍历一棵二叉搜索树,遍历序列的数值是递增排序的. 仅仅须要用中序遍历算法遍历一棵二叉搜索树.就非常easy找出它的第k大结点. 结点定义 private static class BinaryTreeNode { private int val; private BinaryTreeNode left; private BinaryTreeNode right; public BinaryTreeNode()…