<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[michaelhan3的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/michaelhan3</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; michaelhan3]]></copyright><item><title><![CDATA[面试题：自定义聚类函数]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90678759</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90678759</guid><author>michaelhan3</author><pubDate>Wed, 29 May 2019 21:22:05 +0800</pubDate><description><![CDATA[定义一个聚类函数 cluster(int data[], int len, int radius)；
data中的值没有重复，长度为len,
把按照数值的聚类进行分为n组，
对于组G中任意一个数值a,总是能在本组G中找到一个数值b,　使　|a-b| &lt; radius　　.
在函数内部打印出所有n个组成员，分成n行输出

(要求：不能使用数组排序操作)

例如:
   输入 data[] =...]]></description><category></category></item><item><title><![CDATA[28. 数组中出现次数超过一半的数字]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90638647</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90638647</guid><author>michaelhan3</author><pubDate>Tue, 28 May 2019 14:30:33 +0800</pubDate><description><![CDATA[数组中有一个数字出现的次数超过数组长度的一半，请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次，超过数组长度的一半，因此输出2。如果不存在则输出0。

思路：我们设置一个用于记录数字num出现次数的变量，如果数组的下一个元素等于当前num，那么次数就加1，否则次数减1。如果次数减小为0，那么就当当前数组数字设置为num，次数重置为1。继...]]></description><category></category></item><item><title><![CDATA[27. 字符串的排列]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90581062</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90581062</guid><author>michaelhan3</author><pubDate>Mon, 27 May 2019 10:19:30 +0800</pubDate><description><![CDATA[输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。




class Solution {
public:
    vector&lt;string&gt; Permutation(string str) {
        vector&lt;string&gt; re...]]></description><category></category></item><item><title><![CDATA[26. 二叉搜索树与双向链表]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90580564</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90580564</guid><author>michaelhan3</author><pubDate>Mon, 27 May 2019 10:19:23 +0800</pubDate><description><![CDATA[输入一棵二叉搜索树，将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点，只能调整树中结点指针的指向。

思路：二叉搜索树的中序遍历是从小到大排序的。所以得利用中序遍历，将左指针指向前一个元素，右指针指向下一个元素。所以需要递归里需要有一个变量表示前一个节点。注意，需要用指针的指针，否则值传递没有作用。


/*
struct TreeNode {
	int val;
	struct ...]]></description><category></category></item><item><title><![CDATA[25. 复杂链表的复制]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90580255</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90580255</guid><author>michaelhan3</author><pubDate>Mon, 27 May 2019 10:19:16 +0800</pubDate><description><![CDATA[输入一个复杂链表（每个节点中有节点值，以及两个指针，一个指向下一个节点，另一个特殊指针指向任意一个节点），返回结果为复制后复杂链表的head。（注意，输出结果中请不要返回参数中的节点引用，否则判题程序会直接返回空）

思路：由于随机指针的存在，所以最好的办法是先在原始链表的每个元素后面加一个复制的链表。然后循环依次赋值新元素的随机指针，其随机指针是其前一个原始元素的随机指针的next。然后拆分链表...]]></description><category></category></item><item><title><![CDATA[24. 二叉树中和为某一值的路径]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90579900</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90579900</guid><author>michaelhan3</author><pubDate>Mon, 27 May 2019 10:19:08 +0800</pubDate><description><![CDATA[输入一颗二叉树的跟节点和一个整数，打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中，数组长度大的数组靠前)

思路：利用前序遍历，假设处理当前节点，首先将当前节点加入临时数组，如果当前节点是叶子节点，且节点值等于目前节点和还差的数字，那么这就是一条完整的和等于目标值的路径。如果当前节点不是叶子节点，要用...]]></description><category></category></item><item><title><![CDATA[23. 二叉搜索树的后序遍历序列]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90579851</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90579851</guid><author>michaelhan3</author><pubDate>Mon, 27 May 2019 10:19:01 +0800</pubDate><description><![CDATA[输入一个整数数组，判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

思路：对于二叉搜索树来说，最后一个被遍历的是根节点，其左子树都比根节点下，右节点都比根节点大。所以可以当找到根节点后，可以在遍历顺序中，依次比较与根的大小，第一个比根节点大的就是右子树的开始，然后检测右子树是否所有的节点值都比根节点大。然后依次递归的处理。
...]]></description><category></category></item><item><title><![CDATA[22. 从上往下打印出二叉树]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90579711</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90579711</guid><author>michaelhan3</author><pubDate>Mon, 27 May 2019 10:18:24 +0800</pubDate><description><![CDATA[从上往下打印出二叉树的每个节点，同层节点从左至右打印。

思路：就是利用树的层序遍历。建立一个队列，用于存储层序遍历的顺序。


/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {...]]></description><category></category></item><item><title><![CDATA[21.  栈的压入弹出序列]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90574636</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90574636</guid><author>michaelhan3</author><pubDate>Mon, 27 May 2019 10:18:13 +0800</pubDate><description><![CDATA[输入两个整数序列，第一个序列表示栈的压入顺序，请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序，序列4,5,3,2,1是该压栈序列对应的一个弹出序列，但4,3,5,1,2就不可能是该压栈序列的弹出序列。（注意：这两个序列的长度是相等的）

思路：新建一个栈用于存放push数字，当栈顶元素和当前的pop数字相同就将栈顶pop，知道当前...]]></description><category></category></item><item><title><![CDATA[20. 包含min的栈]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90574589</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90574589</guid><author>michaelhan3</author><pubDate>Mon, 27 May 2019 10:17:56 +0800</pubDate><description><![CDATA[定义栈的数据结构，请在该类型中实现一个能够得到栈中所含最小元素的min函数（时间复杂度应为O（1））。

思路：构建两个栈，一个栈s1放普通元素，另一个栈s2放最小值元素，且s2的top元素是目前为止最小的值。当push时，s1正常push，如果当前push值 &lt;= s2 top值，就压入s2。pop时，s1正常pop，如果当前pop值等于s2 top值，就s2也pop。


class S...]]></description><category></category></item><item><title><![CDATA[19. 顺时针打印矩阵]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90574111</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90574111</guid><author>michaelhan3</author><pubDate>Mon, 27 May 2019 10:16:39 +0800</pubDate><description><![CDATA[输入一个矩阵，按照从外向里以顺时针的顺序依次打印出每一个数字，例如，如果输入如下4 X 4矩阵： 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

思路：只需要记录四个边界，然后按照逆时针顺序打印结果就可。注意条件是，左边界 &lt;= 右边界 &amp;&amp; 上边界...]]></description><category></category></item><item><title><![CDATA[18.  二叉树的镜像]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90574055</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90574055</guid><author>michaelhan3</author><pubDate>Sun, 26 May 2019 11:21:16 +0800</pubDate><description><![CDATA[题目描述

操作给定的二叉树，将其变换为源二叉树的镜像。

输入描述:


二叉树的镜像定义：源二叉树 
    	    8
    	   /  \
    	  6   10
    	 / \  / \
    	5  7 9 11
    	镜像二叉树
    	    8
    	   /  \
    	  10   6
    	 / \  / \
    	11 9 7  5
...]]></description><category></category></item><item><title><![CDATA[17.  树的子结构]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90573999</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90573999</guid><author>michaelhan3</author><pubDate>Sun, 26 May 2019 11:16:33 +0800</pubDate><description><![CDATA[输入两棵二叉树A，B，判断B是不是A的子结构。（ps：我们约定空树不是任意一个树的子结构）

思路：个人感觉需要两个递归。假设B是A的子结构。

一个递归是我们要判断从A的哪个节点开始和树B是重复的。

另一个递归是假设当前节点和目标树的根节点一样，那么需要递归的判断接下来的左子树是否和目标左子树相同，右子树是否和目标右子树相同。




/*
struct TreeNode {
	int va...]]></description><category></category></item><item><title><![CDATA[16. 合并两个排序链表]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90573798</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90573798</guid><author>michaelhan3</author><pubDate>Sun, 26 May 2019 10:55:14 +0800</pubDate><description><![CDATA[输入两个单调递增的链表，输出两个链表合成后的链表，当然我们需要合成后的链表满足单调不减规则。

思路：分别用两个指针指向两个链表，依次比较两个指针的值。

建议：为了确定结果链表的第一个节点，最好新建一个节点作为头节点，最后的返回是这个新建节点的下一个节点。


/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int...]]></description><category></category></item><item><title><![CDATA[15. 反转链表]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90573606</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90573606</guid><author>michaelhan3</author><pubDate>Sun, 26 May 2019 10:39:54 +0800</pubDate><description><![CDATA[输入一个链表，反转链表后，输出新链表的表头。

思路：把当前节点的下一个节点的next指针指向当前节点，那么这样就把当前节点和下一个节点反转了。但是为了循环，在改变当前节点下一个节点的next指针时候，应该先记录下来原来的next指针。然后依次循环。


/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) ...]]></description><category></category></item><item><title><![CDATA[14. 链表中倒数第k个节点]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90573491</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90573491</guid><author>michaelhan3</author><pubDate>Sun, 26 May 2019 10:29:12 +0800</pubDate><description><![CDATA[输入一个链表，输出该链表中倒数第k个结点。

思路：两个指针，先让第一个指针走k步，然后两个指针一起走，当前一个指针走到结尾时，后一个指针就是倒数第k个节点。


/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Soluti...]]></description><category></category></item><item><title><![CDATA[13. 调整该数组中数字的顺序，使得所有的奇数位于数组的前半部分，所有的偶数位于数组的后半部分]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90573192</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90573192</guid><author>michaelhan3</author><pubDate>Sun, 26 May 2019 10:00:14 +0800</pubDate><description><![CDATA[输入一个整数数组，实现一个函数来调整该数组中数字的顺序，使得所有的奇数位于数组的前半部分，所有的偶数位于数组的后半部分，并保证奇数和奇数，偶数和偶数之间的相对位置不变。

思路：没有太好的方法，只有牺牲空间了。新建两个数组，一个放奇数，另一个放偶数。

一个建议：判断奇数偶数，最好用 &amp;1，而不用%2。


class Solution {
public:
    void reOrder...]]></description><category></category></item><item><title><![CDATA[12. 数值的整数次方]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90573095</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90573095</guid><author>michaelhan3</author><pubDate>Sun, 26 May 2019 09:48:42 +0800</pubDate><description><![CDATA[给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

思路：详细思路解释请看我的另一篇博客https://blog.youkuaiyun.com/michaelhan3/article/details/88635826


class Solution {
public:
    double Power(double base, int expon...]]></description><category></category></item><item><title><![CDATA[11. 二进制中1的个数]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90573014</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90573014</guid><author>michaelhan3</author><pubDate>Sun, 26 May 2019 09:38:57 +0800</pubDate><description><![CDATA[输入一个整数，输出该数二进制表示中1的个数。其中负数用补码表示。

思路：考虑n = n &amp; (n-1) 表示把n的二进制数字最右边的为1的数字变成0。那么n有多少个二进制位1，就可以进行多少次这样的操作。


class Solution {
public:
     int  NumberOf1(int n) {
         int res = 0;
         while...]]></description><category></category></item><item><title><![CDATA[10. 矩形覆盖]]></title><link>https://blog.youkuaiyun.com/michaelhan3/article/details/90572961</link><guid>https://blog.youkuaiyun.com/michaelhan3/article/details/90572961</guid><author>michaelhan3</author><pubDate>Sun, 26 May 2019 09:34:45 +0800</pubDate><description><![CDATA[我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形，总共有多少种方法？

思路：还是斐波那契数列思路。考虑一下递推的关系，求n个矩形的方法数为s(n)，想象如果第一个矩形是横着放的，那么此时的方法数就是s(n-1)；如果第一个矩形是竖着放的，那么要想铺满，那么也必须有另一个矩形也竖着放，那么这时候方法数就是s(n-2)。综合起来说，s(n)...]]></description><category></category></item></channel></rss>