剑指offer 练习题目

   1 #include <iostream>
   2 #include<vector>
   3 #include <stack>
   4 #include<map>
   5 #include<list>
   6 #include <sstream>
   7 #include <algorithm>//里边有好多现成的函数
   8 #include <queue>
   9 
  10 using namespace std;
  11 
  12 struct TreeNode {
  13     int val;
  14     struct TreeNode *left;
  15     struct TreeNode *right;
  16     TreeNode(int x) :
  17         val(x), left(NULL), right(NULL) {
  18     }
  19 };
  20 struct ListNode {
  21     int val;
  22     struct ListNode *next;
  23     ListNode(int x) :
  24         val(x), next(NULL) {
  25     }
  26 };
  27 struct RandomListNode {
  28     int label;
  29     struct RandomListNode *next, *random;
  30     RandomListNode(int x) :
  31         label(x), next(NULL), random(NULL) {
  32     }
  33 };
  34 struct TreeLinkNode {
  35     int val;
  36     struct TreeLinkNode *left;
  37     struct TreeLinkNode *right;
  38     struct TreeLinkNode *next;
  39     TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
  40     }
  41 };
  42 class Solution {
  43 public:
  44     /*请实现两个函数,分别用来序列化和反序列化二叉树*/
  45     TreeNode* decode(char *&str) {
  46         if (*str == '#'){
  47             str++;
  48             return NULL;
  49         }
  50         int num = 0;
  51         while (*str != ',')
  52             num = num * 10 + (*(str++) - '0');
  53         str++;
  54         TreeNode *root = new TreeNode(num);
  55         root->left = decode(str);
  56         root->right = decode(str);
  57         return root;
  58     }
  59     char* Serialize2(TreeNode *root) {
  60         if (!root) return "#";
  61         string r = to_string(root->val);
  62         r.push_back(',');
  63         char *left = Serialize(root->left);
  64         char *right = Serialize(root->right);
  65         char *ret = new char[strlen(left) + strlen(right) + r.size()];
  66         strcpy_s(ret, sizeof(r.c_str()),r.c_str());
  67         strcat(ret, left);
  68         strcat(ret, right);
  69         return ret;
  70     }
  71     TreeNode* Deserialize2(char *str) {
  72         return decode(str);
  73     }
  74 
  75     char* Serialize(TreeNode *root)
  76     {
  77         //先序遍历 中序遍历 保存结果
  78         if (root == NULL) return NULL;
  79         vector<TreeNode*>preOrder, inOrder;
  80         PreOrder(root, preOrder);
  81         InOrderTraverse(root, inOrder);
  82         
  83         char * combine = new char[preOrder.size()+inOrder.size()+1];
  84         for (int i = 0; i < preOrder.size();i++)
  85         {
  86             combine[i] = preOrder[i]->val;
  87         }
  88         for (int i = preOrder.size(); i < preOrder.size() + inOrder.size(); i++)
  89         {
  90             combine[i] = inOrder[i - preOrder.size()]->val;
  91         }
  92         combine[preOrder.size() + inOrder.size()] = '';
  93         return combine;
  94     }
  95     TreeNode* Deserialize(char *str)
  96     {
  97         int len = strlen(str);
  98         vector<int>preOrder, inOrder;
  99         for (int i = 0; i < len / 2;i++)
 100         {
 101             preOrder.push_back((int)str[i]);
 102         }
 103         for (int i = len/2; i < len; i++)
 104         {
 105             inOrder.push_back((int)str[i]);
 106         }
 107 
 108         return reConstructBinaryTree(preOrder, inOrder);
 109     }
 110     /*请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。
 111         在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,
 112         但是与"aa.a"和"ab*a"均不匹配http://www.voidcn.com/blog/huzhigenlaohu/article/p-6087740.html*/    
 113     bool matchCore(char* str, int strIndex, char* pattern, int patternIndex)
 114     {
 115         //str到尾,pattern到尾,匹配成功
 116         if (strIndex == strlen(str) && patternIndex == strlen(pattern))return true;
 117         //str未到尾,pattern到尾,匹配失败
 118         if (strIndex != strlen(str) && patternIndex == strlen(pattern))    return false;
 119 
 120         //str到尾,pattern未到尾(不一定匹配失败,因为a*可以匹配0个字符)
 121         if (strIndex == strlen(str) && patternIndex != strlen(pattern)) {
 122             //只有pattern剩下的部分类似a*b*c*的形式,才匹配成功
 123             if (patternIndex + 1 < strlen(pattern) && pattern[patternIndex + 1] == '*') {
 124                 return matchCore(str, strIndex, pattern, patternIndex + 2);
 125             }
 126             return false;
 127         }
 128 
 129         //str未到尾,pattern未到尾
 130         if (patternIndex + 1 < strlen(pattern) && pattern[patternIndex + 1] == '*')
 131         {
 132             if (pattern[patternIndex] == str[strIndex] || (pattern[patternIndex] == '.' && strIndex != strlen(str)))
 133             {
 134                 return matchCore(str, strIndex, pattern, patternIndex + 2)//*匹配0个,跳过
 135                     || matchCore(str, strIndex + 1, pattern, patternIndex + 2)//*匹配1个,跳过
 136                     || matchCore(str, strIndex + 1, pattern, patternIndex);//*匹配1个,再匹配str中的下一个
 137             }
 138             else
 139             {
 140                 //直接跳过*(*匹配到0个)
 141                 return matchCore(str, strIndex, pattern, patternIndex + 2);
 142             }
 143         }
 144     }
 145     bool match(char* str, char* pattern)
 146     {
 147         if (strlen(str) == 0 || strlen(pattern) == 0)
 148         {
 149             return false;
 150         }
 151         int strIndex = 0;
 152         int patternIndex = 0;
 153         return matchCore(str, strIndex, pattern, patternIndex);
 154     }
 155     /*地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,
 156     但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),
 157     因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?*/
 158     int sumOfDigits(int n)
 159     {
 160         int sum = 0;
 161         while (n>0)
 162         {
 163             sum += n % 10;
 164             n /= 10;
 165         }
 166         return sum;
 167     }
 168     int count(int threshold, int rows, int cols, int *flag,int i,int j)
 169     {
 170         if (i < 0 || i >= rows || j < 0 || j >= cols || sumOfDigits(i) + sumOfDigits(j) > threshold || flag[i*cols + j] == 1)
 171             return 0;
 172         flag[i*cols + j] = 1;
 173 
 174         return 1 + count(threshold, rows, cols, flag, i + 1, j) +
 175                    count(threshold, rows, cols, flag, i - 1, j) +
 176                    count(threshold, rows, cols, flag, i, j + 1) +
 177                    count(threshold, rows, cols, flag, i, j - 1);
 178 
 179     }
 180     int movingCount(int threshold, int rows, int cols)
 181     {        
 182         int* flag = new int[rows*cols];
 183         for (int i = 0; i < rows*cols;i++)
 184         {
 185             flag[i] = 0;
 186         }
 187         return count(threshold,rows,cols,flag,0,0);
 188     }
 189     /*请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,
 190     每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
 191     例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bccced"的路径,
 192     但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。*/    
 193     /*这是一个可以用回朔法解决的典型题。http://www.voidcn.com/blog/huzhigenlaohu/article/p-6090898.html
 194     首先,在矩阵中任选一个格子作为路径的起点。如果路径上的第i个字符不是ch,那么这个格子不可能处在路径上的第i个位置。
 195     如果路径上的第i个字符正好是ch,那么往相邻的格子寻找路径上的第i+1个字符。除在矩阵边界上的格子之外,其他格子都有4个相邻的格子。
 196     重复这个过程直到路径上的所有字符都在矩阵中找到相应的位置。
 197     由于回朔法的递归特性,路径可以被开成一个栈。当在矩阵中定位了路径中前n个字符的位置之后,
 198     在与第n个字符对应的格子的周围都没有找到第n+1个字符,这个时候只要在路径上回到第n-1个字符,重新定位第n个字符。
 199     由于路径不能重复进入矩阵的格子,还需要定义和字符矩阵大小一样的布尔值矩阵,用来标识路径是否已经进入每个格子。
 200     当矩阵中坐标为(row,col)的格子和路径字符串中相应的字符一样时,从4个相邻的格子(row,col-1),(row-1,col),(row,col+1)
 201     以及(row+1,col)中去定位路径字符串中下一个字符如果4个相邻的格子都没有匹配字符串中下一个的字符,
 202     表明当前路径字符串中字符在矩阵中的定位不正确,我们需要回到前一个,然后重新定位。
 203     一直重复这个过程,直到路径字符串上所有字符都在矩阵中找到合适的位置*/
 204     bool isHasPath(char* matrix,int rows,int cols,int i,int j,char* str,int k,bool* flag)
 205     {
 206         int index = i*cols + j;
 207         if (i < 0 || i >= rows || j < 0 || j >= cols || matrix[index] != str[k] || flag[index]) return false;
 208 
 209         if (k == strlen(str) - 1) return true;
 210         
 211         flag[index] = true;
 212 
 213         if (isHasPath(matrix, rows, cols, i, j + 1, str, k + 1, flag) ||
 214             isHasPath(matrix, rows, cols, i, j - 1, str, k + 1, flag) ||
 215             isHasPath(matrix, rows, cols, i + 1, j, str, k + 1, flag) ||
 216             isHasPath(matrix, rows, cols, i - 1, j, str, k + 1, flag) )            
 217         {
 218             return true;
 219         }
 220         flag[index] = false;
 221         return false;
 222     }
 223     bool hasPath(char* matrix, int rows, int cols, char* str)
 224     {
 225         if (strlen(matrix)<rows*cols || strlen(str)>strlen(matrix)) return false;
 226 
 227         bool* flag = new bool[rows*cols];//标记该位置是否有效        
 228         for (int i = 0; i < rows*cols; i++)flag[i] = false;        
 229         for (int i = 0; i < rows;i++)
 230         { 
 231             for (int j = 0; j < cols;j++)
 232             {
 233                 if (isHasPath(matrix, rows, cols, i, j, str,0, flag))
 234                     return true;
 235             }            
 236         }
 237 
 238         delete[] flag;
 239         return false;
 240     }
 241     /*输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
 242     假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
 243     例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。*/
 244     TreeNode* ConstructTree(vector<int>&pre, vector<int>&vin,int preLeft,int preRight,int vinLeft,int vinRight)
 245     {
 246         if (preLeft > preRight || vinLeft> vinRight)return NULL;
 247 
 248         TreeNode* root = new TreeNode(0);
 249         root->val = pre[preLeft];
 250 
 251          int index = vinLeft;
 252         while (vin[index] != pre[preLeft])index++;//在中序遍历中找到根节点位置
 253         int length = index - vinLeft;//左子树节点个数
 254         //int length2 = vinRight - index;//右子树节点个数
 255 
 256         TreeNode* leftTree = ConstructTree(pre, vin, preLeft + 1, preLeft+length,index-length,index -1);//注意下标
 257         TreeNode* rightTree = ConstructTree(pre, vin, preLeft+length + 1,preRight,index+1,vinRight );
 258 
 259         root->left = leftTree;
 260         root->right = rightTree;
 261         return root;
 262     }
 263     TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
 264     {
 265         if (pre.size() == 0||pre.size()!=vin.size()) return NULL;
 266 
 267         TreeNode* root = new TreeNode(0);        
 268         root->val = pre[0];        
 269         root = ConstructTree(pre, vin, 0, pre.size() - 1, 0, vin.size() - 1);
 270         return root;
 271     }
 272     /*输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
 273     如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。*/
 274     bool isOK(vector<int>&a,int left,int right)
 275     {//抄的 马克(Mark)
 276         if (left >= right) return true;
 277         int  i = right;
 278         while (i > left && a[i - 1] > a[right])i--;//a[right]为根 找到中间左右子树界限
 279         for (int j = i - 1; j >= left;j--)
 280         {
 281             if (a[j] > a[right])return false;//如果左子树有大于根的 返回FALSE
 282         }
 283         return isOK(a, left, i - 1) && isOK(a, i, right - 1);
 284     }
 285     bool VerifySquenceOfBST(vector<int> sequence)
 286     {//BST的后序序列的合法序列是,对于一个序列S,最后一个元素是x (也就是根),如果去掉最后一个元素的序列为T,
 287     //那么T满足:T可以分成两段,前一段(左子树)小于x,后一段(右子树)大于x,且这两段(子树)都是合法的后序序列。完美的递归定义 : ) 。
 288         if (sequence.size() == 0)return false;
 289         return isOK(sequence,0,sequence.size()-1);
 290         
 291     }
 292     /*输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。
 293     要求不能创建任何新的结点,只能调整树中结点指针的指向。*/
 294     void InOrderNonRecursiveTraverse(TreeNode*pRoot, vector<TreeNode*>& result)//非递归中序遍历
 295     {
 296         if (pRoot == NULL)return;
 297         stack<TreeNode*>st;
 298         while (pRoot!=NULL||!st.empty())
 299         {
 300             while (pRoot != NULL)
 301             {
 302                 st.push(pRoot);
 303                 pRoot = pRoot->left;//最左端
 304             }
 305             if (!st.empty())
 306             {
 307                 pRoot = st.top();//出栈
 308                 st.pop();
 309                 result.push_back(pRoot);
 310                 pRoot = pRoot->right;//向右边遍历
 311             }
 312         }
 313     }
 314     TreeNode* Convert(TreeNode* pRootOfTree)
 315     {//首先中序遍历,存储在一个vector里 然后遍历vector建立链表 别人貌似不是这么做的。。么有用vector存储一遍的
 316         if (pRootOfTree == NULL)return pRootOfTree;
 317         vector<TreeNode*> result;
 318         InOrderTraverse(pRootOfTree, result);
 319         
 320         for (int i = 0; i < result.size()-1; i++)
 321         {
 322             result[i]->right = result[i + 1];
 323             result[i + 1]->left = result[i];
 324         }
 325         
 326         return result[0];        
 327     }
 328 
 329     /*给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。
 330     注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。*/    
 331     TreeLinkNode* GetNext(TreeLinkNode* pNode)
 332     {
 333         if (pNode == NULL) return NULL;
 334         if (pNode->right!=NULL)//有右子树
 335         {
 336             pNode = pNode->right;
 337             while (pNode->left!=NULL)
 338             {
 339                 pNode = pNode->left;
 340             }
 341             return pNode;
 342         }
 343 
 344         TreeLinkNode* parent = pNode->next;
 345         while (parent!=NULL )//父亲的父亲的。。。父亲为空停止循环 或者找到 作为父亲的左孩子为止&& parent->next->left != parent 
 346         {
 347             if (parent->left == pNode)//if (parent->next->left ==parent)//原来是这么写的 不对!!!
 348             {
 349                 return parent;//return parent->next;
 350             }
 351             pNode = parent;
 352             parent = parent->next;
 353             
 354         }            
 355         
 356         return NULL;
 357         
 358     }
 359     /*给定一颗二叉搜索树,请找出其中的第k大的结点。
 360     例如, 5 /  3 7 / / 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。*/
 361     void InOrderTraverse(TreeNode*pRoot, vector<TreeNode*>& result)
 362     {
 363         if (pRoot!=NULL)
 364         {
 365             InOrderTraverse(pRoot->left, result);
 366             result.push_back(pRoot);
 367             InOrderTraverse(pRoot->right, result);
 368         }
 369     }
 370     TreeNode* KthNode(TreeNode* pRoot, int k)
 371     {//首先中序遍历 然后返回kth值。。。效率太低了吧。。但是暂时没有高效率方法
 372         if (pRoot == NULL || k <= 0) return NULL;
 373         vector<TreeNode*> result;
 374         InOrderTraverse(pRoot,result);
 375 
 376         if (k > result.size()) return NULL;
 377         return result[k - 1];        
 378     }
 379     /*输入一棵二叉树,判断该二叉树是否是平衡二叉树。*/
 380     //网上有复杂度为O(n)方法
 381     int getTreeDepth(TreeNode* pRoot)
 382     {
 383         if (pRoot == NULL) return 0;
 384         return 1+max(getTreeDepth(pRoot->left),getTreeDepth(pRoot->right));
 385     }
 386     bool IsBalanced_Solution(TreeNode* pRoot)
 387     {
 388         if (pRoot == NULL) return true;
 389         if (!IsBalanced_Solution(pRoot->left))return false;
 390         if (!IsBalanced_Solution(pRoot->right))return false;
 391 
 392         int leftDepth = getTreeDepth(pRoot->left);
 393         int rightDepth = getTreeDepth(pRoot->right);
 394 
 395         if (abs(leftDepth - rightDepth) > 1) return false;
 396         return true;
 397     }
 398     /*输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),
 399     返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)*/
 400     RandomListNode* Clone(RandomListNode* pHead)
 401     {
 402         if (pHead == NULL)
 403             return NULL;
 404 
 405         //开辟一个新节点
 406         RandomListNode* pClonedHead = new RandomListNode(pHead->label);
 407         pClonedHead->next = pHead->next;
 408         pClonedHead->random = pHead->random;
 409 
 410         //递归其他节点
 411         pClonedHead->next = Clone(pHead->next);
 412 
 413         return pClonedHead;
 414         /*if (pHead == NULL)return pHead;
 415         RandomListNode* tempPre = new RandomListNode(0);
 416         tempPre->label = pHead->label;
 417         pHead = pHead->next;
 418         while (pHead != NULL)
 419         {
 420             RandomListNode* tempCur = new RandomListNode(0);
 421             RandomListNode* tempRandom = new RandomListNode(0);
 422             tempPre->next = tempCur;
 423             tempPre->random = tempRandom;
 424 
 425             tempCur->label = pHead->label;            
 426 
 427             temp->label = pHead->label;
 428             temp->next = pHead->next;
 429             temp->random = pHead->random;
 430             pHead = pHead->next;
 431         }*/
 432     }
 433     /*如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。
 434     如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
 435     */
 436     ///别人貌似都不是这么做的。。不知道为啥他们都用堆结构等等。。。不是舍近求远么 
 437     vector<int> data;
 438     void Insert(int num)
 439     {
 440         data.push_back(num);
 441     }
 442     double GetMedian()
 443     {
 444         sort(data.begin(),data.end());
 445         if (data.size() % 2 == 1)
 446         {
 447             return data[data.size() / 2];
 448         }
 449         else
 450             return (data[data.size() / 2] + data[data.size() / 2 - 1]) / 2.0;
 451     }
 452     /*一个链表中包含环,请找出该链表的环的入口结点。*/
 453     ListNode* EntryNodeOfLoop(ListNode* pHead)
 454     {
 455         if (pHead == NULL)return NULL;
 456         map<ListNode*, int> table;//用来记录访问次数
 457         ListNode* entry= NULL;
 458         while (pHead!=NULL)
 459         {
 460             table[pHead]++;
 461             if (table[pHead]==2)
 462             {
 463                 return pHead;
 464             }
 465             pHead = pHead->next;
 466         }
 467         return entry;
 468     }
 469     /*输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)*/
 470     /*class Solution {//别人 de
 471         bool isSubtree(TreeNode* pRootA, TreeNode* pRootB) {
 472             if (pRootB == NULL) return true;
 473             if (pRootA == NULL) return false;
 474             if (pRootB->val == pRootA->val) {
 475                 return isSubtree(pRootA->left, pRootB->left)
 476                     && isSubtree(pRootA->right, pRootB->right);
 477             }
 478             else return false;
 479         }
 480     public:
 481         bool HasSubtree(TreeNode* pRootA, TreeNode* pRootB)
 482         {
 483             if (pRootA == NULL || pRootB == NULL) return false;
 484             return isSubtree(pRootA, pRootB) ||
 485                 HasSubtree(pRootA->left, pRootB) ||
 486                 HasSubtree(pRootA->right, pRootB);
 487         }
 488     };*/
 489     void PreOrder(TreeNode* pRoot, vector<TreeNode*>& result)
 490     {
 491         if (pRoot != NULL)
 492         {
 493             result.push_back(pRoot);
 494             PreOrder(pRoot->left, result);            
 495             PreOrder(pRoot->right, result);
 496         }
 497     }
 498     bool isContain2(vector<TreeNode*>order1, vector<TreeNode*>order2)
 499     {//子串是否包含函数
 500         int N = order1.size();
 501         int M = order2.size();            
 502         for (int i = 0; i <= N - M; i++)//判断连续子串 只需到N-M
 503         {
 504             int j;
 505             for (j = 0; j < M; j++)
 506             {
 507                 if (order1[i + j]->val != order2[j]->val)//是order1[i + j]->val相等 不是order1[i + j]相等
 508                     break;
 509             }
 510             if (j == M)
 511             {
 512                 return true;
 513             }
 514         }
 515         return false;
 516     }
 517     /*测试用例:{8,8,7,9,2,#,#,#,#,4,7},{8,9,2} true*/
 518     bool isContain(vector<TreeNode*>order1, vector<TreeNode*>order2)
 519     {
 520         int N = order1.size();
 521         int M = order2.size();
 522         int j = 0;
 523         for (int i = 0; i < N; i++)//边界条件!此题不需要连续子串
 524         {
 525                         
 526             if (j<M && order1[i]->val==order2[j]->val)
 527             {
 528                 j++;
 529             }            
 530             if (j == M)
 531             {
 532                 return true;
 533             }
 534         }
 535         return false;
 536     }
 537     bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
 538     {//中序遍历和前序遍历 生成字符串 同理判断是否存在包含关系
 539         if (pRoot1 == NULL || pRoot2 == NULL) return false;
 540         vector<TreeNode*>inOrder1, inOrder2,preOrder1,preOrder2;
 541         PreOrder(pRoot1, preOrder1);
 542         PreOrder(pRoot2, preOrder2);
 543 
 544         InOrderTraverse(pRoot1, inOrder1);
 545         InOrderTraverse(pRoot2, inOrder2);
 546 
 547         //判断是否是子串关系
 548         if (isContain(preOrder1, preOrder2) && isContain(inOrder1, inOrder2))
 549             return true;
 550         
 551         return false;
 552 
 553     }
 554     /*请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,
 555     第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。*/    
 556     vector<vector<int> > Print2(TreeNode* pRoot)
 557     {
 558         vector<vector<int> > result;
 559         if (pRoot==NULL)return result;
 560         //首先层次遍历 最后将偶数层 翻转。。。。效率貌似不高。。。 高效率就是 访问偶数层的时候  反着插入
 561         queue<TreeNode*>myqueue;
 562         myqueue.push(pRoot);
 563         int flag = 1;//flag 表示奇数还是偶数层
 564         while (!myqueue.empty())
 565         {
 566             int index = 0, levelSize = myqueue.size();
 567             vector<int> level;
 568             TreeNode* temp;
 569             
 570             while (index++ < levelSize)
 571             {
 572                 temp = myqueue.front();
 573                 myqueue.pop();
 574                 vector<int>::iterator it;
 575 
 576                 if (flag==1)//第奇数层
 577                 {                                    
 578                     level.push_back(temp->val);
 579                 }
 580                 else//第偶数层
 581                 {
 582                     it = level.begin();
 583                     level.insert(it, temp->val);                            
 584                 }
 585                 if (temp->left)    myqueue.push(temp->left);
 586                 if (temp->right)myqueue.push(temp->right);
 587             }
 588             result.push_back(level);
 589             level.clear();
 590             if (flag == 1)flag = 0;
 591             else if (flag == 0)flag = 1;
 592         }
 593         return result;
 594 
 595     }
 596     /*从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。*/
 597     vector<vector<int> > Print(TreeNode* pRoot)
 598     {
 599         /*  vector<vector<int>> ret;
 600         if (pRoot == NULL) return ret;
 601 
 602         queue<TreeNode*> q;
 603         q.push(pRoot);
 604 
 605         while (!q.empty())
 606         {
 607         int low = 0, high = q.size();
 608         vector<int> level;
 609         TreeNode *tmp;
 610 
 611         while (low++ < high)     //按层次来!!!
 612         {
 613         tmp = q.front();
 614         q.pop();
 615         level.push_back(tmp->val);
 616         if (tmp->left)
 617         q.push(tmp->left);
 618         if (tmp->right)
 619         q.push(tmp->right);
 620         }
 621         ret.push_back(level);
 622         level.clear();
 623         }
 624         return ret;*/
 625 
 626         vector<vector<int>> result;
 627         if (pRoot == NULL)return result;
 628         queue<TreeNode*> myqueue;
 629         myqueue.push(pRoot);
 630         int i = 0, levelLen = 1,nextLevelLen = 0;//当前索引  当前层的长度  下一层长度 貌似看别人的方法不用求 利用queue.size 统计队内元素个数
 631         while (!myqueue.empty())
 632         {
 633             vector<int> temp;
 634             while (i < levelLen)
 635             {
 636                 temp.push_back(myqueue.front()->val);
 637                 if (myqueue.front()->left!=NULL)
 638                 {
 639                     myqueue.push(myqueue.front()->left);
 640                     nextLevelLen++;
 641                 }
 642                 if (myqueue.front()->right != NULL)
 643                 {
 644                     myqueue.push(myqueue.front()->right);
 645                     nextLevelLen++;
 646                 }
 647                 myqueue.pop();
 648                 if (i == levelLen-1)//本层最后一个元素  将本层遍历过的元素保存 
 649                 {
 650                     result.push_back(temp);                    
 651                 }                
 652                 i++;
 653             }
 654             levelLen = nextLevelLen; //本层遍历结束 进入下一层
 655             nextLevelLen = 0;
 656             i = 0;//每层从头开始            
 657         }
 658         return result;
 659     }
 660     /*从上往下打印出二叉树的每个节点,同层节点从左至右打印。*/
 661     vector<int> PrintFromTopToBottom(TreeNode* root)
 662     { //层序遍历
 663         vector<int> result;
 664         queue<TreeNode*> myqueue;
 665         if (root == NULL)  return result;
 666 
 667         myqueue.push(root);
 668         while (!myqueue.empty())
 669         {
 670             result.push_back(myqueue.front()->val);
 671             if (myqueue.front()->left != NULL)
 672             {
 673                 myqueue.push(myqueue.front()->left);
 674             }
 675             if (myqueue.front()->right != NULL)
 676             {
 677                 myqueue.push(myqueue.front()->right);
 678             }
 679             myqueue.pop();
 680         }
 681 
 682         return result;
 683 
 684     }
 685     /*请实现一个函数,用来判断一颗二叉树是不是对称的。
 686     注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的*/
 687     bool Symmetrical(TreeNode* pLeft, TreeNode* pRight)
 688     {
 689         if (pLeft == NULL && pRight == NULL)return true;
 690         if ((pLeft == NULL&&pRight != NULL) || (pLeft != NULL&&pRight == NULL))return false;        
 691         if (pLeft->val != pRight->val)return false;
 692         
 693         return Symmetrical(pLeft->left, pRight->right) && Symmetrical(pLeft->right, pRight->left);        
 694     }
 695     bool isSymmetrical(TreeNode* pRoot)
 696     {
 697         if (pRoot == NULL)return true;
 698         return Symmetrical(pRoot, pRoot);
 699     }
 700     /*输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。
 701     路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。*/
 702     vector<vector<int>> result;
 703     vector<int> temp;
 704     void Traverse(TreeNode* root, int expectNumber)
 705     {
 706         temp.push_back(root->val);
 707         if (expectNumber == root->val && root->left==NULL && root->right ==NULL)//正好找到为叶结点
 708         {
 709             result.push_back(temp);
 710         }
 711         else
 712         {
 713             if(root->left)Traverse(root->left, expectNumber - root->val);
 714             if(root->right)Traverse(root->right, expectNumber - root->val);
 715         }
 716         temp.pop_back(); //深度遍历 要回退一个结点
 717     }
 718     vector<vector<int> > FindPath(TreeNode* root, int expectNumber)
 719     {        
 720         if (root == NULL ) return result;
 721 
 722         Traverse(root,expectNumber);
 723         return result;
 724     }
 725     /*操作给定的二叉树,将其变换为源二叉树的镜像。 */
 726     void Mirror(TreeNode *pRoot)
 727     {//递归 类似先序遍历
 728         if (pRoot == NULL)return;
 729         TreeNode* temp = pRoot->left;
 730         pRoot->left = pRoot->right;
 731         pRoot->right = temp;
 732         Mirror(pRoot->left);
 733         Mirror(pRoot->right);
 734         
 735     }
 736     /*求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,
 737     但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。*/
 738     int PowerBase10(unsigned int n)
 739     {        // 10^n
 740         int result = 1;
 741         for (unsigned int i = 0; i < n; ++i)
 742             result *= 10;
 743         return result;
 744     }
 745     int b10(unsigned int n)
 746     {
 747         return PowerBase10(n);
 748     }
 749     int NumberBitCount(unsigned int n)
 750     {
 751         int N = 0;
 752         while (n)
 753         {
 754             n = n / 10;
 755             N++;
 756         }
 757         return N;
 758     }
 759     int NumberOf1Between1AndN_Solution(int n)
 760     {//看不懂 抄的http://www.cnblogs.com/hellogiser/p/3738812.html
 761         // T(n) = o(N) = o(lgn)
 762         if (n<=0)
 763         {
 764             return 0;
 765         }
 766         int N = NumberBitCount(n);
 767         int si, sum = 0;
 768         int A, B, bi, ri;
 769         for (int i = 1; i <= N; i++)
 770         {
 771             A = n / b10(i) * b10(i - 1);
 772             bi = n / b10(i - 1) % 10;
 773             ri = n % b10(i - 1);
 774             if (bi == 0)
 775             {
 776                 B = 0;
 777             }
 778             else if (bi == 1)
 779             {
 780                 B = ri + 1;
 781             }
 782             else if (bi > 1)
 783             {
 784                 B = b10(i - 1);
 785             }
 786             si = A + B;
 787             sum += si;
 788         }
 789         return sum;
 790     }
 791     /*输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。
 792     假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,
 793     序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
 794     (注意:这两个序列的长度是相等的)*/
 795     bool IsPopOrder(vector<int> pushV, vector<int> popV)
 796     {//设置一个辅助栈,将pushV中的数字依次压入栈中,一直检查栈顶元素是否与popV中的第一个数字相等,
 797      //如果相等则弹出栈,不相等就接着将pushV中数字push进栈,直到将所有数字都入栈,如果最后栈不空,则不是弹出序列
 798         /*        if(pushV.size() == 0) return false;//别人的简洁
 799         vector<int> stack;
 800         for(int i = 0,j = 0 ;i < pushV.size();){
 801         stack.push_back(pushV[i++]);
 802         while(j < popV.size() && stack.back() == popV[j]){
 803         stack.pop_back();
 804         j++;
 805         }
 806         }
 807         return stack.empty();*/
 808         if (pushV.size() != popV.size() || pushV.size()<1 || popV.size()<1)return false;
 809         
 810         stack<int>temp;
 811         int i=1,j = 0;
 812         temp.push(pushV[0]);
 813         while (1)
 814         {
 815             while (temp.top() != popV[j] && i < pushV.size())
 816             {
 817                 temp.push(pushV[i++]);
 818             }
 819             if (temp.top() == popV[j])
 820             {
 821                 temp.pop();
 822                 j++;
 823             }
 824             else //将pushV里的数字都入栈了也没有找到
 825             {
 826                 return false;
 827             }
 828             if (temp.size() == 0) //栈最后为空 或者popV为空 说明都匹配完毕
 829             {
 830                 return true;
 831             }
 832         }        
 833         return false;//yong 不上 
 834     }
 835     /*把只包含因子2、3和5的数称作丑数(Ugly Number)。
 836     例如6、8都是丑数,但14不是,因为它包含因子7。
 837     习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。*/
 838     int GetUglyNumber_Solution(int index)
 839     {//参考作者博客http://zhedahht.blog.163.com/blog/static/2541117420094245366965/
 840         if (index < 1)return index;
 841         vector<int>ugly;
 842         ugly.push_back(1);
 843         int index2 = 0, index3 = 0, index5 = 0;
 844         int i = 1;
 845         while (i<index)
 846         {            
 847             ugly.push_back(std::min(ugly[index2] * 2, std::min(ugly[index3] * 3, ugly[index5] * 5)));
 848             while (ugly[index2] * 2 <= ugly[i])
 849                 index2++;
 850             while (ugly[index3] * 3 <= ugly[i])
 851                 index3++;
 852             while (ugly[index5] * 5 <= ugly[i])
 853                 index5++;
 854             i++;
 855         }
 856         return ugly[index - 1];
 857     }
 858     /*请实现一个函数用来找出字符流中第一个只出现一次的字符。*/
 859     //Insert one char from stringstream
 860     //用map来统计出现次数
 861     map<char, int>table;
 862     vector<char>charStream;
 863     void Insert(char ch)
 864     {
 865         charStream.push_back(ch);
 866         table[ch]++;
 867     }
 868     //return the first appearence once char in current stringstream
 869     char FirstAppearingOnce()
 870     {
 871         vector<char>::iterator it;
 872         for (it = charStream.begin(); it != charStream.end();it++)
 873         {
 874             if (table[*it]==1)
 875             {
 876                 return *it;
 877             }
 878         }
 879         return '#';
 880     }
 881     /*输入两个链表,找出它们的第一个公共结点。*/
 882     int getListLength(ListNode* pHead)
 883     {
 884         int length = 0;
 885         if (pHead == NULL)return length;
 886         while (pHead)
 887         {
 888             pHead = pHead->next;
 889             length++;
 890         }
 891         return length;
 892     }
 893     ListNode *move(ListNode* list,int length)
 894     {
 895         while (length)
 896         {
 897             list = list->next;
 898             length--;
 899         }
 900         return list;
 901     }
 902     ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2)
 903     {//首先求两个链表长度,做差  同时向后移动
 904         int length1 = 0, length2 = 0;
 905         length1 = getListLength(pHead1);
 906         length2 = getListLength(pHead2);
 907         if (length1 == 0)return NULL;
 908         if (length2 == 0)return NULL;
 909         ListNode* temp1 = pHead1;
 910         ListNode* temp2 = pHead2;
 911         if (length1>length2)
 912         {
 913             temp1 = move(pHead1, length1 - length2);
 914         }
 915         else if (length1<length2)
 916         {
 917             temp2 = move(pHead2, length2 - length1);
 918         }
 919         while (temp1&&temp2)
 920         {
 921             if (temp1==temp2)
 922             {
 923                 return temp1;
 924             }
 925             else
 926             {
 927                 temp1 = temp1->next;
 928                 temp2 = temp2->next;
 929             }
 930         }
 931 
 932         return NULL;        
 933     }
 934     /*扑克牌顺子 大王用0表示   可以表示任何数字*/
 935     bool IsContinuous(vector<int> numbers)
 936     {
 937         if (numbers.size() != 5)return false;
 938         sort(numbers.begin(),numbers.end());
 939         int zreos = 0, gap = 0;//记录0的个数 和记录差距 
 940         for (int i = 0; i < numbers.size();i++)
 941         {
 942             if (numbers[i] == 0)zreos++;
 943             else if (i + 1 < numbers.size())
 944             {
 945                 if (numbers[i] == numbers[i + 1])return false;
 946                 gap += numbers[i + 1] - numbers[i] - 1;                
 947             }
 948         }
 949         if (gap>zreos)        //差距大于0的个数
 950             return false;
 951         return true;
 952         
 953     }
 954     /*输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序*/
 955     vector<vector<int> > FindContinuousSequence(int sum) 
 956     {
 957         vector<vector<int>> result;
 958         if (sum <= 2)return result;
 959 
 960         for (int a = 1; a <= sum / 2;a++)
 961         {
 962             float b;
 963             b = (-1 + sqrt(1 + 4 * a*a - 4 * a + 8 * sum)) / 2;
 964             if ((b-(int)b)==0)//如果b是整数 则存在序列
 965             {
 966                 vector<int> temp;
 967                 for (int i = a; i <= b;i++)
 968                 {
 969                     temp.push_back(i);
 970                 }
 971                 result.push_back(temp);
 972             }
 973         }
 974         return result;
 975     }
 976     /*输入一个递增排序的数组和一个数字S,在数组中查找两个数,
 977     是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。 */
 978     vector<int> FindNumbersWithSum(vector<int> array, int sum)
 979     {//别人写的o(n)的复杂度
 980         /* vector<int> result;
 981         int length = array.size();
 982         int start = 0;
 983         int end = length - 1;
 984         while (start < end)
 985         {
 986         if (array[start] + array[end] == sum)
 987         {
 988         result.push_back(array[start]);
 989         result.push_back(array[end]);
 990         break;
 991         }
 992         else if (array[start] + array[end] < sum)
 993         start++;
 994         else
 995         end--;
 996         }*/
 997         vector<int>result;
 998         if (array.size() <= 1)return result;
 999         for (int i = 0; i < array.size() - 1;i++)
1000         {
1001             for (int j = array.size() - 1; j>i;j--)
1002             {
1003                 if (array[i]+array[j]==sum)
1004                 {
1005                     result.push_back(array[i]);
1006                     result.push_back(array[j]);
1007                     //break; 退出循环
1008                     i = array.size();
1009                 }                
1010             }
1011         }
1012         return result;
1013 
1014     }
1015     /*定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。*/
1016     stack<int>s1, min1;
1017     void push1(int value)
1018     {
1019         s1.push(value);
1020         if (min1.empty())min1.push(value);
1021         if (min1.top()>=value)
1022         {
1023             min1.push(value);
1024         }
1025     
1026     }
1027     void pop1()
1028     {
1029         s1.pop();
1030         if (s1.top() == min1.top())min1.pop();
1031     }
1032     int top()
1033     {
1034         return s1.top();
1035     }
1036     int min()
1037     {
1038         return min1.top();
1039     }
1040 
1041     /*输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。*/
1042     ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
1043     {//别人写的
1044         //ListNode* result = NULL;
1045         //ListNode* current = NULL;
1046 
1047         //if (pHead1 == NULL)return pHead2;
1048         //if (pHead2 == NULL)return pHead1;
1049         ///*if (pHead1->val <= pHead2->val)//递归版本
1050         //{
1051         //    result = pHead1;
1052         //    result->next = Merge(pHead1->next, pHead2);
1053         //}
1054         //else
1055         //{
1056         //    result = pHead2;
1057         //    result->next = Merge(pHead1, pHead2->next);
1058         //}*/
1059         //      
1060         //while (pHead1 != NULL && pHead2 != NULL){
1061         //    if (pHead1->val <= pHead2->val){
1062         //        if (result == NULL){
1063         //            current = result = pHead1;
1064         //        }
1065         //        else {
1066         //            current->next = pHead1;
1067         //            current = current->next;
1068         //        }
1069         //        pHead1 = pHead1->next;
1070         //    }
1071         //    else {
1072         //        if (result == NULL){
1073         //            current = result = pHead2;
1074         //        }
1075         //        else {
1076         //            current->next = pHead2;
1077         //            current = current->next;
1078         //        }
1079         //        pHead2 = pHead2->next;
1080         //    }
1081         //}
1082 
1083         //if (pHead1 == NULL)    current->next = pHead2;        
1084         //if (pHead2 == NULL)    current->next = pHead1;        
1085         //return result;
1086 
1087         if (pHead1 == NULL)return pHead2;
1088         if (pHead2 == NULL)return pHead1;
1089 
1090         ListNode* head = pHead2;
1091         ListNode* tempNode = pHead1->next;
1092         ListNode* tempNode2= pHead2;        
1093         while (pHead1)    //将list1中结点挨个插入到list2中的合适位置
1094         {
1095             bool isHead = true;//用来标记是否将list1的结点插入到list2的头部
1096             while (pHead2 && pHead1->val > pHead2->val)//找到合适位置 大于当前 
1097             {
1098                 tempNode2 = pHead2;//tempNode2用来保存phead2前边结点
1099                 pHead2 = pHead2->next;
1100                 isHead = false;
1101             }
1102             if (isHead)//插入头部
1103             {                
1104                 tempNode = pHead1->next;//保存list1中下一个结点
1105                 pHead1->next = pHead2;
1106                 //tempNode2->next = pHead1;
1107                 head = pHead1;                
1108             }
1109             else//非头部
1110             {
1111                 if (pHead2)//插入结点 此时list2中存在结点
1112                 {
1113                     tempNode = pHead1->next;//保存list1中下一个结点
1114                     pHead1->next = pHead2;
1115                     tempNode2->next = pHead1;                    
1116                 }
1117                 else//插到list2最后
1118                 {
1119                     tempNode = pHead1->next;
1120                     tempNode2->next = pHead1;
1121                     pHead1->next = pHead2;//此时pHead2==NULL
1122                 }
1123             }
1124             pHead1 = tempNode;//开始list1中的下一结点
1125             if (tempNode)
1126             {tempNode = tempNode->next;    
1127             }
1128             
1129             pHead2 = head; //从list2 的头开始遍历
1130         }
1131 
1132         return head;
1133     }
1134     /*数组中的逆序对:在数组中的两个数字,如果前面一个数字大于后面的数字,
1135     则这两个数字组成一个逆序对。输入一个数组,
1136     求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。
1137     即输出P%1000000007 
1138     题目保证输入的数组中没有的相同的数字
1139     输入例子:    1,2,3,4,5,6,7,0 
1140     输出例子:    7 */
1141     //:出处http://blog.csdn.net/ns_code/article/details/27520535
1142     long long MergePairsBetweenArray(int *arr, int *brr, int start, int mid, int end)
1143     {
1144         int i = mid;
1145         int j = end;
1146         int k = end;  //辅助数组的最后一位  
1147         long long count = 0;
1148 
1149         //设置两个指针i,j分别从右往左依次比较,  
1150         //将较大的依次放入辅助数组的右边  
1151         while (i >= start && j >= mid + 1)
1152         {
1153             if (arr[i] > arr[j])
1154             {
1155                 count += j - mid;
1156                 brr[k--] = arr[i--];
1157             }
1158             else
1159                 brr[k--] = arr[j--];
1160         }
1161 
1162         //将其中一个数组中还剩下的元素拷贝到辅助数组中,  
1163         //两个循环只会执行其中的一个  
1164         while (i >= start)
1165             brr[k--] = arr[i--];
1166         while (j >= mid + 1)
1167             brr[k--] = arr[j--];
1168 
1169         //从辅助数组中将元素拷贝到原数组中,使其有序排列  
1170         for (i = end; i > k; i--)
1171             arr[i] = brr[i];
1172 
1173         return count;
1174     }
1175     long long CountMergePairs(int *arr, int *brr, int start, int end)
1176     {
1177         long long PairsNum = 0;
1178         if (start < end)
1179         {
1180             int mid = (start + end) >> 1;
1181             PairsNum += CountMergePairs(arr, brr, start, mid); //统计左边子数组的逆序对  
1182             PairsNum += CountMergePairs(arr, brr, mid + 1, end); //统计右边子数组的逆序对  
1183             PairsNum += MergePairsBetweenArray(arr, brr, start, mid, end); //统计左右子数组间的逆序对  
1184         }
1185         return PairsNum;
1186     }
1187     int InversePairs(vector<int> data)
1188     {
1189         if (data.size() == 0)return 0;
1190         long long count = 0;
1191         //for (int i = 0; i < data.size() - 1;i++)//时间复杂度太大 不通过
1192         //for (int j = i + 1; j < data.size(); j++)
1193         //if (data[i]>data[j])count++;
1194         
1195         //vector<int> temp(data.size());//初始化向量的大小
1196     
1197         int *brr = new int[data.size()];
1198         for (int i = 0; i < data.size();i++)
1199         {
1200             brr[i] = data[i];
1201         }
1202         int *temp = new int[data.size()];
1203 
1204         count = CountMergePairs(brr, temp, 0, data.size() - 1);
1205 
1206 
1207         return count % 1000000007;
1208     }
1209     /*在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)
1210     中找到第一个只出现一次的字符,并返回它的位置*/
1211     int FirstNotRepeatingChar(string str)
1212     {
1213         if (str.size() == 0)return -1;
1214         //构造一个hash表 统计出现次数
1215         map<char, int> table;
1216         for (char i = 'A'; i <= 'Z';i++) table[i] = 0;
1217         char *p = new char[str.size()+1];  
1218         str.copy(p, str.size(), 0);
1219         
1220         for (int i = 0; i < str.size();i++)    table[str[i]]++;
1221         map<char, int>::iterator it;
1222         int pos = str.size();
1223         for (it = table.begin(); it != table.end();it++)
1224         {
1225             if (it->second == 1 && pos>str.find_first_of(it->first))//只出现一次
1226             {
1227                 pos = str.find_first_of(it->first);
1228             }
1229         }
1230         if (pos == str.size())
1231         {
1232             return -1;
1233         }
1234         else
1235             return pos;
1236         
1237     }
1238     /*{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止(子向量的长度至少是1)*/
1239     int FindGreatestSumOfSubArray(vector<int> array)
1240     {
1241         if (array.size() < 1) return 0;
1242         int max = array[0],sum = 0;
1243         //int result = array[0];//作为记录单次遍历最大和
1244         
1245         //如果左边总和为负数 那么从下一个值开始 O(n)复杂度 效率高
1246         for (int i = 0; i < array.size();i++)
1247         {
1248             if (sum < 0)
1249             {
1250                 sum = array[i];
1251             }
1252             else
1253             {
1254                 sum += array[i];
1255             }
1256             if (max < sum)max = sum;
1257             
1258         }
1259 
1260         //for (int i = 0; i < array.size();i++) //效率低
1261         //{
1262         //    result = array[i];
1263         //    sum = 0;
1264         //    for (int j = i; j < array.size(); j++)
1265         //    {
1266         //        sum += array[j];
1267         //        if (result < sum)
1268         //        {
1269         //            result = sum;
1270         //        }
1271         //    }
1272         //    if (max<result)
1273         //    {
1274         //        max = result;
1275         //    }
1276 
1277         //}
1278         
1279         return max;
1280     }
1281     /*约瑟夫环 让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列,
1282     下一个继续0...m-1报,问最后剩下谁*/
1283     int LastRemaining_Solution(int n, int m)
1284     {
1285         if (n == 0)
1286             return -1;
1287         if (n == 1)
1288             return 0;
1289         else
1290             return (LastRemaining_Solution(n - 1, m) + m) % n;//参考的别人的
1291 
1292         if (m <= 0||n<1)return -1;
1293         list<int>* table = new list<int>();
1294         for (int i = 1; i <= n;i++)    table->push_back(i);
1295         
1296         int count = 1;
1297         for (list<int>::iterator it = table->begin(); table->size() != 1;)
1298         {            
1299             if (count == m)
1300             {
1301                 cout << " " <<*it;
1302                 it = table->erase(it);                
1303                 count = 0;
1304             }
1305             else
1306             {
1307                 it++;
1308             }
1309             if (it == table->end())
1310             {
1311                 it = table->begin();
1312             }
1313             count++;
1314         }
1315         //cout << endl<<"The last one is:";
1316         cout << *table->begin() << endl;
1317 
1318         return *table->begin();
1319         return 0;
1320 
1321     }
1322     //堆排序,root为根节点下标
1323     void heapSort(vector<int> &input, int root, int end)
1324     {
1325         for (int j = end - 1; j >= root; j--)
1326         {
1327             int parent = (j + root - 1) / 2;
1328             if (input[parent] > input[j])
1329             {
1330                 int temp = input[j];
1331                 input[j] = input[parent];
1332                 input[parent] = temp;
1333             }
1334         }
1335     }
1336     /*输入n个整数,找出其中最小的K个数。
1337     例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,*/
1338     vector<int> GetLeastNumbers_Solution(vector<int> input, int k)
1339     {
1340         vector<int> result;
1341         if (input.size() < k||k<=0)return result;
1342         sort(input.begin(), input.end());
1343         for (int i = 0; i < k;i++)
1344         {
1345             result.push_back(input[i]);
1346         }
1347         return result;
1348     }
1349     /*输入一个字符串,按字典序打印出该字符串中字符的所有排列。
1350     例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串
1351     abc,acb,bac,bca,cab和cba。输入一个字符串,长度不超过9(可能有字符重复),
1352     字符只包括大小写字母。*/
1353     void digui(char *sortStr, int begin, int end, vector<string>& result)
1354     {
1355         if (begin == end)
1356         {
1357             string str;
1358             //for (int i = 0; i < end; i++) str += sortStr[i];
1359             str = sortStr;
1360             result.push_back(str);
1361             //result.push_back(sortStr);//其实可以直接这样
1362             return;
1363         }
1364         else
1365         {
1366             for (int i = begin; i < end;i++)
1367             {    
1368                 swap(sortStr[begin],sortStr[i]);
1369                 digui(sortStr, begin+1, end, result);
1370                 swap(sortStr[begin], sortStr[i]);
1371             }
1372         }
1373 
1374     }
1375     vector<string> Permutation(string str)
1376     {
1377         vector<string> result;
1378         if (str.size() == 0) return result;
1379     //    const char* tempStr = new char[str.size() + 1];tempStr = str.c_str();        
1380         char* sortStr = new char[str.size() + 1];//有了这个就可以啦
1381         //for (int i = 0; i < str.size(); i++) sortStr[i] = tempStr[i];
1382         str.copy(sortStr, str.size(),0);
1383         sortStr[str.size()] = '';
1384         cout << sortStr << endl;
1385         //递归
1386         digui(sortStr, 0, str.size(), result);
1387         sort(result.begin(), result.end());
1388         //for (int i = 0; i < str.size()-1;i++)//排序        
1389         //    for (int j = 0; j<str.size()-i-1;j++)            
1390         //        if (sortStr[j]>sortStr[j + 1]){ char temp = sortStr[j];    sortStr[j] = sortStr[j+1]; sortStr[j+1] = temp; }
1391             
1392         //去除重复项
1393         for (auto  it = result.begin() + 1; it != result.end();)
1394         {
1395             if (*it == *(it - 1))
1396                 it = result.erase(it);
1397             else
1398                 it++;
1399         }    
1400 
1401         return result;
1402         
1403     }
1404     vector<string> Permutation2(string str) {//网上看别人写的 LuL
1405         vector<string> out;
1406         int len = str.length();
1407         if (len == 0)
1408             return out;
1409         char* p = (char *)malloc((len + 1)*sizeof(char));
1410         str.copy(p, len, 0);
1411 
1412         //全排列,迭代
1413         myPermutation(p, 0, len, out);
1414         //字典序排序
1415         sort(out.begin(), out.end());
1416         //去除重复项
1417         for (auto it = out.begin() + 1; it != out.end();){
1418             if (*it == *(it - 1))
1419                 it = out.erase(it);
1420             else
1421                 it++;
1422         }
1423         return out;
1424     }
1425 
1426     void myPermutation(char* p, int k, int m, vector<string>& out){
1427         if (k == m){
1428             //将结果存入out中
1429             string s;
1430             for (int i = 0; i < m; ++i)
1431                 s += p[i];
1432             out.push_back(s);
1433             return;
1434         }
1435         for (int i = k; i < m; ++i){
1436             swap(p[k], p[i]);
1437             myPermutation(p, k + 1, m, out);
1438             swap(p[k], p[i]);
1439         }
1440     }
1441     /*汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。
1442     对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。
1443     例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。*/
1444     string LeftRotateString(string str, int n)
1445     {
1446         if (str.size()==0 || n<0)    return "";
1447         if (n>str.size()) n %= str.size();
1448         const char*  sequence = str.c_str();
1449         char* roateStr = new char[str.size() + 1];
1450         char* doubleSeq = new char[2 * str.size()+1];  //建立一个双倍的字符串类似 abcXYZdefabcXYZdef可直接返回结果 
1451         for (int i = 0; i < str.size();i++)
1452         {
1453             doubleSeq[i] = sequence[i];
1454             doubleSeq[i+str.size()] = sequence[i];
1455         }
1456         doubleSeq[2 * str.size()] = '';
1457         for (int i = 0; i < str.size(); i++)///这种情况不需要开辟一个双倍空间了 复杂度为O(n)
1458         {
1459             //roateStr[i] = doubleSeq[i+n];
1460             if ((i+n)<str.size())
1461             {
1462                 roateStr[i] = sequence[i + n];
1463             }
1464             else
1465             {
1466                 roateStr[i] = sequence[i+n-str.size()];
1467             }
1468             
1469         }
1470         roateStr[str.size() + 1] = '';
1471         //cout << doubleSeq << endl;
1472         //cout << roateStr << endl;
1473         return roateStr;
1474     }
1475     /*数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
1476     例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。
1477     由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。*/
1478     int MoreThanHalfNum_Solution(vector<int> numbers)
1479     {//用map hash存储关键字 统计出现次数  看到别人用 map.count() 作为查找 good~
1480         if (numbers.size() == 0)
1481         {
1482             return 0;
1483         }
1484         map<int, int> mapValue;
1485         map<int, int>::iterator iter;
1486         for (int i = 0; i < numbers.size(); i++)
1487         {
1488             mapValue[numbers[i]] = 0;//初始化
1489         }
1490         for (int i = 0; i < numbers.size(); i++)//统计出现次数
1491         {        
1492             mapValue[numbers[i]]++;
1493         }
1494         for (iter = mapValue.begin(); iter != mapValue.end(); iter++)
1495         {
1496             if (iter->second*2 > numbers.size())
1497             {
1498                 return iter->first;
1499             }
1500         }
1501         return 0;
1502 
1503     }
1504     /*牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,
1505     写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,
1506     但却读不懂它的意思。例如,“student. a am I”。
1507     后来才意识到,这家伙原来把句子单词的顺序翻转了,
1508     正确的句子应该是“I am a student.”。
1509     Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?*/
1510     string ReverseSentence(string str)
1511     {//下面6行是马克(Mark)的方法。。。够简洁。。学习了
1512         /*string res = "", tmp = "";
1513         for (unsigned int i = 0; i < str.size(); ++i){
1514             if (str[i] == ' ') res = " " + tmp + res, tmp = "";
1515             else tmp += str[i];
1516         }
1517         if (tmp.size()) res = tmp + res;
1518         return res;*/
1519         if (str.size() == 0) return str;///这块儿不能返回NULL 返回""就行
1520         
1521         //首先分出单词 然后统计单词个数 
1522         string reverse = "";
1523         const char *temp = str.c_str();
1524         cout << temp << endl;
1525 
1526         //split word
1527         int i = 0,wordStart = 0,wordEnd = 0;    
1528         vector<string> strVec;//保存所有单词
1529         while (temp[i] != '')
1530         {        
1531             if (temp[i] ==' ')//先假设单词间都是1个空格 结尾没有空格
1532             {
1533                 wordEnd = i - 1;
1534                 char word[128];
1535                 int k = 0;
1536                 for (int j = wordStart; j <= wordEnd;j++)//
1537                 {                    
1538                     word[k] = temp[j];
1539                     k++;
1540                 }                
1541                 word[k] = '';                
1542                 strVec.push_back(word);                
1543                 wordStart = i + 1;
1544             }            
1545             i++;
1546         }
1547         wordEnd = i - 1;    
1548         char word[128];
1549         int k = 0;
1550         for (int j = wordStart; j <= wordEnd; j++)//
1551         {            
1552             word[k] = temp[j];
1553             k++;
1554         }        
1555         word[k] = '';        
1556         strVec.push_back(word);        
1557 
1558         for (int i = 0; i < strVec.size()/2;i++)
1559         {
1560             string temp = strVec[i];
1561             strVec[i] = strVec[strVec.size() - 1 - i];
1562             strVec[strVec.size() - 1 - i] = temp;
1563         }
1564 
1565         for (int i = 0; i < strVec.size();i++)
1566         {
1567             //cout << strVec[i].c_str() << " ";
1568             if (i != strVec.size()-1)  reverse = reverse + strVec[i].c_str() + " ";
1569             else    reverse = reverse + strVec[i].c_str();
1570         }
1571 
1572         return reverse;
1573     }
1574     /*请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。
1575     例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。
1576     但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。*/
1577     bool isNumeric(char* string)
1578     {
1579         int i = 0;
1580         if (string[i] == '+' || string[i] == '-'||isdigit(string[i]))//判断第一位
1581         {
1582             while (string[++i] != ''&&isdigit(string[i]));//检测到第一个非数字符号
1583             
1584             if (string[i]=='.')
1585             {
1586                 if (isdigit(string[++i]))//小数点后下一位是否是数字
1587                 {
1588                     while (string[++i] != ''&&isdigit(string[i]));//检测到第一个非数字符号
1589 
1590                     if (string[i] == 'e' || string[i] == 'E')
1591                     {
1592                         i++;
1593                         if (string[i] == '+' || string[i] == '-' || isdigit(string[i]))
1594                         {
1595                             while (string[++i] != '' && isdigit(string[i]));
1596                             if (string[i] == '') return true;
1597                             else return false;
1598                         }
1599                         else return false;
1600                     }
1601                     else if (string[i] == '')
1602                     {
1603                         return true;
1604                     }
1605                     else return false;
1606                 }
1607                 else
1608                     return false;
1609             }
1610             else if (string[i] == 'e' || string[i] == 'E')
1611             {
1612                 i++;
1613                 if (string[i] == '+' || string[i] == '-' || isdigit(string[i]))
1614                 {
1615                     while (string[++i] != '' && isdigit(string[i]));
1616                     if (string[i] == '') return true;
1617                     else return false;
1618                 }
1619                 else return false;
1620             }
1621             else if (string[i] == '')
1622             {
1623                 return true;
1624             }
1625             else
1626                 return false;//其他情况 非数字
1627         }
1628         else
1629         {
1630             return false;
1631         }
1632     }
1633     /*///网上说用双端队列~~~~~~~....待优化
1634     给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。
1635     例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,
1636     他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个:
1637     {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1},
1638     {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
1639     */
1640     vector<int> maxInWindows(const vector<int>& num, unsigned int size)
1641     {
1642         vector<int> maxInWindow;
1643         if (size > num.size()|| size == 0) return maxInWindow;
1644         
1645         for (int i = 0; i < num.size() + 1 - size;i++)
1646         {
1647             //在下标范围为[i  i+1 ...i+size-1]找最大值
1648             int max = num[i];
1649 
1650             for (int j = 0; j < size;j++)
1651             {
1652                 if (max < num[i+j])
1653                 {
1654                     max = num[i+j];
1655                 }
1656             }
1657             maxInWindow.push_back(max);
1658         }
1659 
1660         return maxInWindow;
1661     }
1662     /*在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,
1663     重复的结点不保留,返回链表头指针。 
1664     例如,链表1->2->3->3->4->4->5 处理后为 1->2->5*/
1665     ListNode* deleteDuplication(ListNode* pHead)
1666     {//参考别人的思路改写的。。牛客网id :Charles_Lee
1667         
1668         if (pHead == NULL) return NULL;
1669 
1670         //定义一个临时头结点,防止头结点被删除
1671         ListNode* pTempHead = new ListNode(0);
1672         pTempHead->next = pHead;
1673 
1674         
1675         ListNode* pCur = pHead, *pLast = pTempHead;//ptemp
1676         int toDeleteVal = 0;
1677         while (pCur && pCur->next)
1678         {
1679             if (pCur->val == pCur->next->val)//当前值和下一个相等 往后移动 知道不相等或空
1680             {
1681                 toDeleteVal = pCur->val;
1682                 while (pCur && pCur->val == toDeleteVal)
1683                 {                                                    
1684                     pCur = pCur->next;
1685                 }
1686                 pLast->next = pCur;
1687             }
1688             else//当前和下一个不相等,则当前肯定不被删除 判断下一个
1689             {
1690                 pLast = pCur;
1691                 pCur = pCur->next;
1692             }
1693 
1694         }
1695         
1696         return pTempHead->next;
1697         
1698         
1699     }
1700     /*统计一个数字在排序数组中出现的次数。网上好多二分查找 递归什么的。。。待优化*/
1701     int GetNumberOfK(vector<int> data, int k)
1702     {
1703         int count = 0;
1704         for (int i = 0; i < data.size(); i++)
1705         {
1706             if (data[i] == k)
1707             {
1708                 count++;
1709             }
1710         }
1711         return count;
1712 
1713     }
1714     /*将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。
1715     数值为0或者字符串不是一个合法的数值则返回0
1716     输入描述:    输入一个字符串,包括数字字母符号,可以为空
1717     输出描述:    如果是合法的数值表达则返回该数字,否则返回0
1718     输入例子:    +2147483647    1a33
1719     输出例子:    2147483647    0
1720     */
1721     int StrToInt(string str)
1722     {
1723         if (str.size() == 0)
1724         {
1725             return 0;
1726         }
1727         int  value = 0;
1728 
1729         //char* temp;
1730         /*temp = new char[str.size() + 1];
1731         strcpy_s(temp,strlen(temp), str.c_str());*//////牛客网上编译不通过 因为strcpy_s()没有
1732         const char * temp;
1733         temp = str.c_str();
1734 
1735         cout << temp << endl;
1736 
1737         if (temp[0] == '+' || temp[0] == '-')
1738         {
1739             for (int i = 1; temp[i] != ''; i++)
1740             {
1741                 if (temp[i] >= '0' && temp[i] <= '9')
1742                 {
1743                     value = value * 10 + temp[i] - '0';
1744                 }
1745                 else
1746                 {
1747                     return 0;
1748                 }
1749             }
1750             if (temp[0] == '+')
1751             {
1752                 return value;
1753             }
1754             else
1755             {
1756                 return -value;
1757             }
1758 
1759         }
1760         else if (temp[0] >= '0'&&temp[0] <= '9')
1761         {
1762             for (int i = 0; temp[i] != ''; i++)
1763             {
1764                 if (temp[i] >= '0' && temp[i] <= '9')
1765                 {
1766                     value = value * 10 + temp[i] - '0';
1767                 }
1768                 else
1769                 {
1770                     return 0;
1771                 }
1772             }
1773             return value;
1774         }
1775         return 0;////这儿在牛客网上必须写 否则编译不通过。
1776 
1777     }
1778     /*用两个栈来实现一个队列,完成队列的Push和Pop操作。
1779     队列中的元素为int类型。*/
1780     void push(int node)
1781     {
1782         stack1.push(node);
1783     }
1784 
1785     int pop()
1786     {
1787         int result, temp;
1788         while (!stack1.empty())//将所有元素放到stack2里
1789         {
1790             temp = stack1.top();
1791             stack1.pop();
1792             stack2.push(temp);
1793         }
1794         result = stack2.top();//保存一下要弹出队列的第一个元素
1795         stack2.pop();
1796         while (!stack2.empty())
1797         {
1798             temp = stack2.top();
1799             stack2.pop();
1800             stack1.push(temp);
1801         }
1802         return result;
1803 
1804     }
1805 
1806     /*在一个长度为n的数组里的所有数字都在0到n-1的范围内。
1807     数组中某些数字是重复的,但不知道有几个数字是重复的。
1808     也不知道每个数字重复几次。请找出数组中任意一个重复的数字。
1809     例如,如果输入长度为7的数组{2,3,1,0,2,5,3},
1810     那么对应的输出是重复的数字2或者3。*/
1811     // Parameters:
1812     //        numbers:     an array of integers
1813     //        length:      the length of array numbers
1814     //        duplication: (Output) the duplicated number in the array number
1815     // Return value:       true if the input is valid, and there are some duplications in the array number
1816     //                     otherwise false
1817     bool duplicate(int numbers[], int length, int* duplication)
1818     {
1819 
1820         int *flags = new int[length];//标记数组
1821         for (int i = 0; i < length; i++)
1822         {
1823             flags[i] = 0;//初始化为0
1824         }
1825         for (int i = 0; i < length; i++)
1826         {
1827             flags[numbers[i]]++;
1828         }
1829         for (int i = 0; i < length; i++)
1830         {
1831             if (flags[i] >= 2)
1832             {
1833                 *duplication = i;
1834             }
1835 
1836         }
1837         if (*duplication >= 0 && *duplication<length)
1838         {
1839             return true;
1840         }
1841         return false;
1842 
1843     }
1844     /*一个整型数组里除了两个数字之外,其他的数字都出现了两次。
1845     请写程序找出这两个只出现一次的数字。
1846     网上说用异或的方法。。。没太明白好处在哪*/
1847     void FindNumsAppearOnce(vector<int> data, int* num1, int *num2)
1848     {
1849         if (data.size() < 2)
1850         {
1851             return;
1852         }
1853         bool flag = false;
1854         vector<int> result;
1855         for (int i = 0; i < data.size(); i++)
1856         {
1857             flag = false;
1858             for (int j = 0; j < data.size(); j++)
1859             {
1860                 if (!flag && i != j && data[i] == data[j])
1861                 {
1862                     flag = true;
1863                 }
1864             }
1865             if (!flag)
1866             {
1867                 result.push_back(data[i]);
1868             }
1869         }
1870         *num1 = result[0];
1871         *num2 = result[1];////////////////这样写num1 = &result[0];  结果不对
1872 
1873 
1874     }
1875     /*求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case
1876     等关键字及条件判断语句(A?B:C)。*/
1877     int Sum_Solution(int n)
1878     {
1879         //参考别人的方法,利用&&操作 666
1880         int sum = n;
1881         (n>0) && (sum += Sum_Solution(n - 1));
1882 
1883         return sum;
1884     }
1885 
1886     /*给定一个数组A[0,1,...,n-1],
1887     请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。
1888     不能使用除法。*/
1889     //待优化
1890     vector<int> multiply(const vector<int>& A)
1891     {
1892         int b = 1;
1893         vector<int> B;
1894         for (int i = 0; i < A.size(); i++)
1895         {
1896             b = 1;
1897             for (int j = 0; j < A.size(); j++)
1898             {
1899                 if (j != i)
1900                 {
1901                     b *= A[j];
1902                 }
1903 
1904             }
1905             B.push_back(b);
1906         }
1907         return B;
1908     }
1909 
1910     /*写一个函数,求两个整数之和,
1911     要求在函数体内不得使用+、-、*、/四则运算符号。*/
1912     int Add(int num1, int num2)
1913     {
1914         /*1.异或为不带进位的加法
1915         2.进位的求法可以通过 两数相与: 1 1才会得1,然后左移1位
1916         3.将步骤2和步骤1的值相加*/
1917         //if (num2 == 0)
1918         //    return num1;
1919         //int temp = num1^num2;    
1920         //int carry = (num1&num2) << 1;        
1921         //return Add(temp, carry);
1922 
1923         //非递归版本
1924         while (num2 != 0)
1925         {
1926             int temp = num1^num2;
1927             num2 = (num1&num2) << 1;
1928             num1 = temp;
1929         }
1930         return num1;
1931 
1932     }
1933     /*输入一个正整数数组,把数组里所有数字拼接起来排成一个数,
1934     打印能拼接出的所有数字中最小的一个。
1935     例如输入数组{ 3,32,321 },
1936     则打印出这三个数字能排成的最小数字为321323。*/
1937     static bool compare(string str1,string str2)///需要加上static 修饰符
1938     {
1939         string s1 = str1 + str2;
1940         string s2 = str2 + str1;
1941         return s1 < s2;
1942     }
1943     string PrintMinNumber(vector<int> numbers)
1944     {
1945         string result;
1946         if (numbers.size() == 0)return result;
1947 
1948         vector<string> allResult;
1949         for (int i = 0; i < numbers.size();i++)
1950         {
1951             stringstream  ss;
1952             ss<<numbers[i];//将不同类型的值转换成string类型的好方法
1953             allResult.push_back(ss.str());
1954         }
1955         sort(allResult.begin(),allResult.end(),compare);
1956         for (int i = 0; i < numbers.size();i++)
1957         {
1958             result.append(allResult[i]);//值得学习的方法 
1959         }
1960         return result;
1961     }
1962     /*把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
1963     输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
1964     例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
1965     NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
1966     //网上说是2分查找最好*/
1967     int minNumberInRotateArray(vector<int> rotateArray)
1968     {
1969         int size = rotateArray.size();
1970         if (size == 0)
1971         {
1972             return 0;
1973         }
1974         int min = rotateArray[0];
1975         for (int i = 0; i < size; i++)
1976         {
1977 
1978             if ((i + 1 < size) && (rotateArray[i]> rotateArray[i + 1]))
1979             {
1980                 min = rotateArray[i + 1];
1981             }
1982         }
1983         return min;
1984 
1985     }
1986     /*输入一个链表,输出该链表中倒数第k个结点。*/
1987     ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
1988     {
1989         if (pListHead == NULL || k <= 0)
1990         {
1991             return NULL;
1992         }
1993 
1994         //首先从头结点开始  算上头结点在内访问k 个结点 然后从头结点和此节点一起向前推进
1995         //直到前边那个结点到最后一个结点  此时前边那个结点即为所求
1996         ListNode *resultNode = pListHead;
1997         ListNode *currentNode = pListHead;
1998         for (int i = 0; i < k - 1; i++)
1999         {
2000             if (currentNode->next == NULL)
2001             {
2002                 return NULL;
2003             }
2004             currentNode = currentNode->next;
2005         }
2006 
2007         while (currentNode->next != NULL)
2008         {
2009             resultNode = resultNode->next;
2010             currentNode = currentNode->next;
2011         }
2012 
2013         return resultNode;
2014 
2015     }
2016     /*输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,
2017     所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。*/
2018     void reOrderArray(vector<int> &array)
2019     {
2020         //扫描一趟,分别记录奇数 和偶数
2021         vector<int> odd, even;
2022 
2023         for (int i = 0; i < array.size(); i++)
2024         {
2025             if (array[i] % 2 == 1)
2026             {
2027                 odd.push_back(array[i]);
2028             }
2029             else
2030             {
2031                 even.push_back(array[i]);
2032             }
2033         }
2034         int oddSize = odd.size();
2035         int evenSize = even.size();
2036 
2037         for (int i = 0; i < oddSize; i++)
2038         {
2039             array[i] = odd[i];
2040         }
2041         for (int j = oddSize; j < oddSize + evenSize; j++)
2042         {
2043             array[j] = even[j - oddSize];
2044         }
2045 
2046     }
2047     /*我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。
2048     请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?*/
2049     int rectCover(int number)
2050     {
2051         if (number == 1 || number == 2)
2052         {
2053             return number;
2054         }
2055         else
2056         {
2057             return rectCover(number - 1) + rectCover(number - 2);
2058         }
2059     }
2060     /*给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。*/
2061     double Power(double base, int exponent)
2062     {
2063         double result = 1.0;
2064 
2065         if (exponent == 0)
2066         {
2067             return 1.0;
2068         }
2069         else if (exponent > 0)
2070         {
2071             for (int i = 0; i < exponent; i++)
2072             {
2073                 result *= base;
2074             }
2075             return result;
2076         }
2077         else
2078         {
2079             exponent = -exponent;
2080             for (int i = 0; i < exponent; i++)
2081             {
2082                 result *= base;
2083             }
2084             return 1 / result;
2085         }
2086 
2087 
2088     }
2089     /*输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示*/
2090     int  NumberOf1(int n) {
2091         //每一位均需判断
2092         int count = 0;
2093         int flag = 1;
2094         while (flag != 0) {
2095             if ((n & flag) != 0) {
2096                 count++;
2097             }
2098 
2099             flag = flag << 1;
2100         }
2101         return count;
2102     }
2103     /*大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。*/
2104     int Fibonacci(int n) 
2105     {
2106         if (n <= 0)    return 0;        
2107         if (n == 1 || n == 2)        
2108             return 1;
2109         else            
2110             return Fibonacci(n - 1) + Fibonacci(n - 2);
2111     }
2112     /*一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。*/
2113     int jumpFloorII(int number)
2114     {
2115       if (number <= 0)    return -1;
2116       if (number == 1)    return 1;
2117       else    return 2 * jumpFloorII(number - 1);
2118     
2119      }
2120     /*一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。*/
2121     int jumpFloor(int number)
2122     {
2123         if (number == 1)return 1;            
2124         else if (number == 2)return 2;
2125         return jumpFloor(number - 1) + jumpFloor(number - 2);
2126     }
2127     /*输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
2128     例如,如果输入如下矩阵: 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.*/
2129     vector<int> printMatrix(vector<vector<int> > matrix)
2130     {
2131         int row = matrix.size();
2132         int col = matrix[0].size();
2133         vector<int> a;
2134         //参考的别人的代码。。。   上地https://www.nowcoder.com/profile/709885
2135         if (row == 0 || col == 0)  return a;
2136         // 定义四个关键变量,表示左上和右下的打印范围
2137         int left = 0, top = 0, right = col - 1, bottom = row - 1;
2138         while (left <= right && top <= bottom)
2139         {
2140             // left to right
2141             for (int i = left; i <= right; ++i)  a.push_back(matrix[top][i]);
2142             // top to bottom
2143             for (int i = top + 1; i <= bottom; ++i)  a.push_back(matrix[i][right]);
2144             // right to left
2145             if (top != bottom)
2146             for (int i = right - 1; i >= left; --i)  a.push_back(matrix[bottom][i]);
2147             // bottom to top
2148             if (left != right)
2149             for (int i = bottom - 1; i > top; --i)  a.push_back(matrix[i][left]);
2150             left++, top++, right--, bottom--;
2151         }
2152         return a;
2153     }
2154     /*输入一个链表,反转链表后,输出链表的所有元素。*/
2155     ListNode* ReverseList(ListNode* pHead)
2156     {
2157         if (pHead == NULL)
2158             return pHead;
2159         ListNode *curNode = pHead;
2160         ListNode *nextNode = curNode->next;
2161         ListNode *temp;
2162         if (curNode->next != NULL)
2163         {
2164             pHead = curNode->next;
2165         }
2166         curNode->next = NULL;
2167         //保存当前结点指针 下一个结点指针 还有下一个的下一个结点指针
2168         while (nextNode)
2169         {
2170             pHead = nextNode;
2171             temp = nextNode->next;
2172             nextNode->next = curNode;
2173 
2174             curNode = nextNode;
2175             nextNode = temp;
2176         }
2177         return pHead;
2178     }
2179     /*输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。*/
2180     int TreeDepth(TreeNode* pRoot)
2181     {
2182         if (pRoot == NULL)
2183         {
2184             return 0;
2185         }
2186         int a = TreeDepth(pRoot->left);
2187         int b = TreeDepth(pRoot->right);
2188         return 1 + (a > b ? a : b);
2189     }
2190     /*输入一个链表,从尾到头打印链表每个节点的值。*/
2191    vector<int> printListFromTailToHead(ListNode* head)
2192     {
2193         vector<int> a;
2194         if (head != NULL)
2195         {
2196             a.insert(a.begin(), head->val);
2197             while (head->next != NULL)
2198             {
2199                 head = head->next;
2200                 a.insert(a.begin(), head->val);
2201             }
2202         }
2203         return a;
2204     }
2205    /*实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。*/
2206    void replaceSpace(char *str, int length)
2207    {
2208         if (str == NULL || length <= 0)        return;        
2209         int i = 0;
2210         int oldLength = 0;
2211         int space = 0;
2212         while (str[i] != '')
2213         {
2214             oldLength++;
2215             if (str[i] == ' ')    space++;            
2216             i++;
2217         }
2218         int newLength = oldLength + space * 2;//新的字符串长度     
2219         if (newLength > length)    return;
2220         while (oldLength >= 0)
2221         {
2222             if (str[oldLength] == ' ')
2223             {
2224                 str[newLength--] = '0';
2225                 str[newLength--] = '2';
2226                 str[newLength--] = '%';
2227             }
2228             else
2229             {
2230                 str[newLength--] = str[oldLength];
2231             }
2232 
2233             oldLength--;
2234         }
2235     }
2236    /*在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
2237    请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。*/
2238     bool Find(int target, vector<vector<int> > array)
2239     {
2240            int colNum;
2241            int rowNum;
2242            rowNum = array.size();
2243            colNum = array[0].size();
2244            bool flag = false;
2245            int j = 0;
2246            int i = rowNum - 1;
2247            while (!flag)
2248            {
2249                if (0 <= i && j <= colNum - 1)
2250                {
2251                    if (array[i][j] < target)   j++;                  
2252                    else if (array[i][j] > target)  i--;             
2253                    else if (array[i][j] == target) flag = true;
2254                }
2255                else       break;              
2256            }
2257            return flag;
2258      }
2259 
2260 private:
2261     stack<int> stack1;
2262     stack<int> stack2;
2263 };
2264 
2265 int main()
2266 {
2267     ListNode node1(1), node2(2), node3(3), node4(4), node5(9),node6(5);
2268     ListNode* resultNode= NULL;
2269     node1.next = &node3;
2270     node2.next = &node4;
2271     node3.next = &node5;
2272     node4.next = &node6;
2273     node5.next = &node4;
2274     vector<int> test,popV;
2275     
2276     test.push_back(1);
2277     test.push_back(2);
2278     test.push_back(4);
2279     test.push_back(7);
2280     test.push_back(3);
2281     test.push_back(5);
2282     test.push_back(6);
2283     test.push_back(8);
2284 
2285     popV.push_back(4);
2286     popV.push_back(7);
2287     popV.push_back(2);
2288     popV.push_back(1);
2289     popV.push_back(5);
2290     popV.push_back(3);
2291     popV.push_back(8);
2292     popV.push_back(6);    
2293 
2294 
2295     Solution sl;
2296     vector<vector<int>> result;
2297     vector<TreeNode*> tree;
2298     
2299     TreeNode * root;
2300 
2301     root = sl.reConstructBinaryTree(test, popV);
2302 
2303 //    cout << sl.Serialize(root);
2304     for (int i = 0; i < strlen(sl.Serialize(root));i++)
2305     {
2306         cout <<(int)sl.Serialize(root)[i] << " ";
2307     }
2308     
2309     cout <<  endl;
2310 
2311     TreeNode * root2;
2312     root2 = sl.Deserialize(sl.Serialize(root));
2313     for (int i = 0; i < strlen(sl.Serialize(root2)); i++)
2314     {
2315         cout << (int)sl.Serialize(root2)[i] << " ";
2316     }
2317     
2318     for (int i = 0; i < tree.size();i++)
2319     {        
2320         cout << tree[i]->val << " ";
2321     }    
2322 
2323     getchar();
2324     return 0;
2325 }

已经上传到 github上,请朋友们多多指教。

https://github.com/jiawenhao2015/nowcoder

原文地址:https://www.cnblogs.com/hellowooorld/p/6415654.html