zoukankan      html  css  js  c++  java
  • 牛客剑指offer 67题(持续更新~)

    第一题:二维数组的查找

    题目描述

    在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
     

    题解:

    由于二维数组数从左到右递增,从上到下递增,那么,我们可以考虑从左下角查找,如果val大于array[i][j]的话,j++,如果小于a[i][j]的话,i--,否则输出true表示找到了val;
    如果到最后都没有找到,说明不存在该元素,返回false:表示没有该元素。
     

    参考代码:

     1 class Solution {
     2 public:
     3   bool Find(int target, vector<vector<int> > array) {
     4     // array是二维数组,这里没做判空操作
     5     int rows = array.size();
     6     int cols = array[0].size();
     7     int i=rows-1,j=0;//左下角元素坐标
     8     while(i>=0 && j<cols){//使其不超出数组范围
     9       if(target<array[i][j])
    10         i--;//查找的元素较少,往上找
    11       else if(target>array[i][j])
    12         j++;//查找元素较大,往右找
    13       else
    14         return true;//找到
    15     }
    16     return false;
    17   }
    18 };
    C++

    第二题:替换空格

    题目描述

    请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
     

    题解:

    我们先统计出来空格的数量,计算出替换后的字符串的长度,然后从后往前替换即可。
     

    参考代码:

     View Code
    1 public class Solution {
    2     public String replaceSpace(StringBuffer str) {
    3         return str.toString().replaceAll("\s", "%20");
    4     }
    5 }
    View Code

    第三题:从尾到头打印字符

    题目描述

    输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

     题解:

    每次插入到vector的头部直到head==NULL;

     参考代码:

     1 /**
     2 *  struct ListNode {
     3 *        int val;
     4 *        struct ListNode *next;
     5 *        ListNode(int x) :
     6 *              val(x), next(NULL) {
     7 *        }
     8 *  };
     9 */
    10 class Solution {
    11 public:
    12     vector<int> printListFromTailToHead(ListNode* head) 
    13     {
    14         vector<int> ans;
    15         while(head!=NULL)
    16         {
    17             ans.insert(ans.begin(),head->val);
    18             head=head->next;
    19         }
    20         return ans;
    21         
    22     }
    23 };
    C++

    第四题:重建二叉树

    题目描述

    输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
     

    题解:

      例如:前序遍历 GDAFEMHZ
         中序遍历 ADEFGHMZ
       则根据前序遍历规则知道树根为G,那么我们在中序遍历中找到根,那么根G 左边的一定是该根的左子树的节点,根右边的元素一定是根右子树的节点;
      我们这样递归即可得到原二叉树。

    参考代码:

     1 /**
     2  * Definition for binary tree
     3  * struct TreeNode {
     4  *     int val;
     5  *     TreeNode *left;
     6  *     TreeNode *right;
     7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     8  * };
     9  */
    10 class Solution {
    11 public:
    12     TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
    13         if(pre.size()==0||pre.size()!=vin.size()) return NULL;
    14         
    15         vector<int> pre_left,pre_right;
    16         vector<int> inl,inr;
    17         TreeNode *node=new TreeNode(pre[0]);
    18         int rootindex;
    19         //找到中序遍历数组中根的位置
    20         for(int i=0;i<vin.size();++i)
    21         {
    22             if(vin[i]==pre[0])
    23             {
    24                 rootindex=i;
    25                 break;
    26             }
    27         }
    28         //左子树元素
    29         for(int i=0;i<rootindex;++i)
    30         {
    31             inl.push_back(vin[i]);
    32             if(i+1<pre.size()) pre_left.push_back(pre[i+1]);
    33         }
    34         //右子树元素
    35         for(int i=rootindex+1;i<vin.size();++i)
    36         {
    37             inr.push_back(vin[i]);
    38             pre_right.push_back(pre[i]);
    39         }
    40         
    41         node->left=reConstructBinaryTree(pre_left,inl);
    42         node->right=reConstructBinaryTree(pre_right,inr);
    43         
    44         return node;
    45     }
    46 };
    C++
     1 /**
     2  * Definition for binary tree
     3  * public class TreeNode {
     4  *     int val;
     5  *     TreeNode left;
     6  *     TreeNode right;
     7  *     TreeNode(int x) { val = x; }
     8  * }
     9  */
    10 public class Solution {
    11     public TreeNode reConstructBinaryTree(int [] pre,int [] in) 
    12     {
    13         TreeNode node=func(pre,0,pre.length-1,in,0,in.length-1);
    14         return node;
    15     }
    16     public TreeNode func(int [] pre,int pre_start,int pre_end,int [] in,int in_start,int in_end)
    17     {
    18         if(pre_start>pre_end||in_start>in_end)
    19         {
    20             return null;
    21         }
    22         TreeNode node = new TreeNode(pre[pre_start]);
    23         
    24         for(int i=in_start;i<=in_end;++i)
    25         {
    26             if(in[i]==pre[pre_start])
    27             {
    28                 node.left=func(pre,pre_start+1,pre_start+i-in_start,in,in_start,i-1);
    29                 node.right=func(pre,pre_start+i-in_start+1,pre_end,in,i+1,in_end);
    30                 
    31                 break;
    32             }
    33         }
    34         return node;
    35     }
    36 }
    Java

     第五题:用两个栈来实现一个队列

    题目描述

    用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
     

    题解:

    对于push操作,我们直接放入stack1中,对于pop操作,我们先判断stack2是否空,不空就输出stack2的栈顶元素即可;为空就把stack1中的元素放入到stack2中然后输出stack2的栈顶元素;

    参考代码:

     1 class Solution
     2 {
     3 public:
     4     void push(int node) {
     5         stack1.push(node);
     6     }
     7 
     8     int pop() {
     9         int ans;
    10         if(!stack2.empty())
    11             ans=stack2.top(),stack2.pop();
    12         else
    13         {
    14             while(!stack1.empty())
    15             {
    16                 stack2.push(stack1.top());
    17                 stack1.pop();
    18             }
    19             ans=stack2.top(),stack2.pop();
    20         }
    21         return ans;
    22     }
    23 
    24 private:
    25     stack<int> stack1;
    26     stack<int> stack2;
    27 };
    C++
     1 import java.util.Stack;
     2 
     3 public class Solution {
     4     Stack<Integer> stack1 = new Stack<Integer>();
     5     Stack<Integer> stack2 = new Stack<Integer>();
     6     
     7     public void push(int node) {
     8         stack1.push(node);
     9     }
    10     
    11     public int pop() {
    12         if(!stack2.empty()) 
    13             return stack2.pop();
    14         else
    15         {
    16                while(!stack1.empty())
    17                {
    18                    stack2.push(stack1.pop());
    19                 }
    20             return stack2.pop();
    21         }
    22     }
    23 }
    Java

    第六题:旋转数组最小的数字

    题目描述

    把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
    输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
    例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
    NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
     

    题解:

    就是找数组的最小值。

    参考代码:

     1 class Solution {
     2 public:
     3     int minNumberInRotateArray(vector<int> array) {
     4         if(!array.size()) return 0;
     5         int ans=array[0];
     6         for(int i=1;i<array.size();++i)
     7             ans=min(ans,array[i]);
     8         return ans;
     9     }
    10 };
    C++
     1 import java.util.ArrayList;
     2 public class Solution {
     3     public int minNumberInRotateArray(int [] array) {
     4         if(array.length==0) return 0;
     5         int ans=array[0];
     6         for(int i=1;i<array.length;++i)
     7         {
     8             if(array[i]<ans) ans=array[i];
     9         }
    10         return ans;
    11         
    12     }
    13 }
    Java

    第七题:斐波那契数列

    题目描述

    大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。

    n<=39

    题解:

    a[n]=a[n-1]+a[n-2];

    参考代码:

     1 class Solution {
     2 public:
     3     int Fibonacci(int n) {
     4         int a=1,b=1;
     5         if(n==0) return 0;
     6         if(n==1||n==2) return 1;
     7         for(int i=3;i<=n;++i)
     8         {
     9             int c=a;
    10             a=a+b;
    11             b=c;
    12         }
    13         return a;
    14     }
    15 };
    C++
     1 public class Solution {
     2     public int Fibonacci(int n) {
     3         int a=1,b=1;
     4         if(n==0) return 0;
     5         if(n==1||n==2) return 1;
     6         for(int i=3;i<=n;++i)
     7         {
     8             int c=a;
     9             a=a+b;
    10             b=c;
    11         }
    12         return a;
    13     }
    14 }
    Java

    第八题:跳台阶

    题目描述

    一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

    题解:

    本质也是斐波那契数列

    参考代码:

    1 class Solution {
    2 public:
    3     int jumpFloor(int number) {
    4         if(number==1) return 1;
    5         if(number==2) return 2;
    6         return jumpFloor(number-1)+jumpFloor(number-2);
    7     }
    8 };
    C++
    1 public class Solution {
    2     public int JumpFloor(int number) {
    3         if(number==1) return 1;
    4         if(number==2) return 2;
    5         return JumpFloor(number-1)+JumpFloor(number-2);
    6     }
    7 }
    Java

    第九题:变态跳台阶

    题目描述

    一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
     

    题解:

    和斐波那契数列推导一样,这个推一下吧。

    用Fib(n)表示青蛙跳上n阶台阶的跳法数,青蛙一次性跳上n阶台阶的跳法数1(n阶跳),设定Fib(0) = 1;

    当n = 1 时,只有一种跳法,即1阶跳:Fib(1) = 1;

    当n = 2 时,有两种跳的方式,一阶跳和二阶跳:Fib(2) = Fib(1) + Fib(0) = 2;

    当n = 3 时,有三种跳的方式,第一次跳出一阶后,后面还有Fib(3-1)中跳法;第一次跳出二阶后,后面还有Fib(3-2)中跳法;第一次跳出三阶后,后面还有Fib(3-3)中跳法

    当n = n 时,共有n种跳的方式,第一次跳出一阶后,后面还有Fib(n-1)中跳法;第一次跳出二阶后,后面还有Fib(n-2)中跳法…第一次跳出n阶后,后面还有 Fib(n-n)中跳法.

    Fib(n) = Fib(n-1)+Fib(n-2)+Fib(n-3)+……….+Fib(n-n)=Fib(0)+Fib(1)+Fib(2)+…….+Fib(n-1)
    又因为Fib(n-1)=Fib(0)+Fib(1)+Fib(2)+…….+Fib(n-2)

    两式相减得:Fib(n) = 2*Fib(n-1) n >= 2

    参考代码:

     1 class Solution {
     2 public:
     3     int jumpFloorII(int number) {
     4        if(number==0) return 0;
     5        int ans=1;
     6         for(int i=1;i<number;++i)
     7             ans=ans*2;
     8         return ans;
     9     }
    10 };
    C++
    1 public class Solution {
    2     public int JumpFloorII(int number) {
    3         if(number==0) return 0;
    4        int ans=1;
    5         for(int i=1;i<number;++i)
    6             ans=ans*2;
    7         return ans;
    8     }
    9 }
    Java

    第十题:矩形覆盖

    题目描述

    我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
     

    题解:

    n=1 :只有横放一个矩形一种解决办法
    n=2 :有横放一个矩形,竖放两个矩形两种解决办法
    n=3 :n=2的基础上加1个横向,n=1的基础上加2个竖向
    n=4n=3的基础上加1个横向,n=2的基础上加2个竖向

    ...

    n=n :n = f(n-1) + f(n-2)

    参考代码:

     1 class Solution {
     2 public:
     3     int rectCover(int n) {
     4         if(n==0) return 0;
     5         if(n==1) return 1;
     6         if(n==2) return 2;
     7         int a=2,b=1,c;
     8         for(int i=3;i<=n;++i)
     9         {
    10             c=a;
    11             a=a+b;
    12             b=c;
    13         }
    14         return a;
    15     }
    16 };
    C++
     1 public class Solution {
     2     public int RectCover(int n) {
     3         if(n==0) return 0;
     4         if(n==1) return 1;
     5         if(n==2) return 2;
     6         int a=2,b=1,c;
     7         for(int i=3;i<=n;++i)
     8         {
     9             c=a;
    10             a=a+b;
    11             b=c;
    12         }
    13         return a;
    14     }
    15 }
    Java

     第十一题:二进制中一的个数

    题目描述

    输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

    题解:

    每次n&(n-1)即可以把最后一个一取出来;

    参考代码:

     1 class Solution {
     2 public:
     3      int  NumberOf1(int n) {
     4         int ans=0;
     5          while(n)
     6          {
     7              n&=(n-1);
     8              ans++;
     9         }
    10          return ans;
    11      }
    12 };
    C++
     1 public class Solution {
     2     public int NumberOf1(int n) {
     3         int ans=0;
     4          while(n!=0)
     5          {
     6              n&=(n-1);
     7              ans++;
     8         }
     9          return ans;
    10     }
    11 }
    Java

    第十二题:数值的整数次方

    题目描述

    给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
     
    保证base和exponent不同时为0

    题解:

    注意正负号,快速幂即可;

     

    参考代码:

     1 class Solution {
     2 public:
     3     double Power(double b, int e) {
     4         if(e==0) return 1;
     5         if(e==1) return b;
     6         double res=1;
     7         int tmp=0;
     8         if(e<0) e=-e,tmp=1;
     9         
    10         while(e!=0)
    11        {
    12            if(e&1) res=res*b;
    13            b=b*b;
    14            e>>=1;
    15        }
    16         if(tmp==1) res=1.0/res;
    17         
    18         return res;
    19     }
    20 };
    C++
     1 public class Solution {
     2     public double Power(double b, int ee) {
     3         if(ee==0) return 1;
     4         if(ee==1) return b;
     5         double res=1;
     6         int tmp=0;
     7         if(ee<0)
     8         {
     9             ee=-ee;
    10             tmp=1;
    11         }
    12         
    13         while(ee!=0)
    14        {
    15            if((ee&1)==1) res=res*b;
    16            b=b*b;
    17            ee>>=1;
    18        }
    19         if(tmp==1) res=1.0/res;
    20         
    21         return res;
    22   }
    23 }
    Java

    第十三题:调整该数组中数字的顺序

    题目描述

    输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

     题解:

    我们用 i记录奇数的位置,j表示偶数的左边界,每次遇到一个奇数,就把j~i-1的偶数向后移一位,然后把这个奇数放到第j个位置上,j++;

    参考代码:

     1 class Solution {
     2 public:
     3     void reOrderArray(vector<int> &array) {
     4         vector<int> t1,t2;
     5         int i,j;
     6         for(i=0;i<array.size();i++){
     7             if(array[i]%2!=0){
     8                 t1.push_back(array[i]);
     9             }else{
    10                 t2.push_back(array[i]);
    11             }
    12         }
    13         for(i=0;i<t1.size();i++){
    14             array[i]=t1[i];
    15         }
    16         for(j=0;j<t2.size()&&i<array.size();j++,i++){
    17             array[i]=t2[j];
    18         }
    19     }
    20 };
    C++
     1 public class Solution {
     2     public void reOrderArray(int[] array) {
     3         int j = 0;
     4         for (int i = 0; i < array.length; i++) {
     5             if (array[i] % 2 == 1) {
     6                 //如果是奇数的话
     7                 if (i != j) {
     8                     int temp = array[i];
     9                     int k = i;
    10                     for (k = i; k > j; k--) {
    11                         array[k] = array[k - 1];
    12                     }
    13                     array[k] = temp;
    14 
    15                 }
    16                 j++;
    17             }
    18         }
    19     }
    20 }
    Java

    第十四题:输出链表中倒数第k个结点

    题目描述

    输入一个链表,输出该链表中倒数第k个结点。

     题解:

    用快慢指针法,快指针先走k-1步,然后快慢指针一起移动即可。

    参考代码:

     1 /*
     2 struct ListNode {
     3     int val;
     4     struct ListNode *next;
     5     ListNode(int x) :
     6             val(x), next(NULL) {
     7     }
     8 };*/
     9 class Solution {
    10 public:
    11     ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
    12         ListNode* p=pListHead;
    13         ListNode* q=pListHead;
    14         int i=0;
    15         for(;p!=NULL;i++)
    16         {
    17             if(i>=k)
    18                 q=q->next;
    19             p=p->next;
    20         }
    21         if(i<k)
    22             return NULL;
    23         else
    24             return q;
    25     }
    26 };
    C++
     1 /*
     2 public class ListNode {
     3     int val;
     4     ListNode next = null;
     5 
     6     ListNode(int val) {
     7         this.val = val;
     8     }
     9 }*/
    10 public class Solution {
    11     public ListNode FindKthToTail(ListNode pListHead,int k) {
    12         ListNode p=pListHead;
    13         ListNode q=pListHead;
    14         int i=0;
    15         for(;p!=null;i++)
    16         {
    17             if(i>=k)
    18                 q=q.next;
    19             p=p.next;
    20         }
    21         if(i<k)
    22             return null;
    23         else
    24             return q;
    25     }
    26 }
    Java

    第十五题:反转链表

    题目描述

    输入一个链表,反转链表后,输出新链表的表头。
     

    题解:

    记录3个指针,pre,now,next
    pre:表示now的前一个节点,now:表示当前节点,next:表示now的下一个节点(可能为NULL);
    每次让
    next=now->next;
    now->next=pre;
    pre=now;
    now=next;
    结束标志为 now==NULL;
    最后输出指针now就行了。

    参考代码:

     1 /*
     2 struct ListNode {
     3     int val;
     4     struct ListNode *next;
     5     ListNode(int x) :
     6             val(x), next(NULL) {
     7     }
     8 };*/
     9 class Solution {
    10 public:
    11     ListNode* ReverseList(ListNode* pHead) {
    12        ListNode *reverse=NULL;
    13        ListNode *node=pHead;
    14        ListNode *pre=NULL;
    15        while(node!=NULL)
    16        {
    17             ListNode *next=node->next;
    18             if(next==NULL)
    19                 reverse=node;
    20             node->next=pre;
    21             pre=node;
    22             node=next;
    23         }
    24         return reverse;
    25     }
    26 };
    C++
     1 public class Solution {
     2     public ListNode ReverseList(ListNode head) {
     3         ListNode pre = null;
     4         ListNode now = head;
     5         ListNode aft = null;
     6         while(now != null){
     7             aft = now.next;
     8             now.next=pre;
     9             pre = now;
    10             now = aft;
    11         }
    12         return pre;
    13     }
    14 }
    Java

    第十六题 反转链表

    时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:662243
    本题知识点: 链表

     算法知识视频讲解

    题目描述

    输入一个链表,反转链表后,输出新链表的表头。

    题解:

      记录3个指针即可。

    参考代码:

    public class Solution {
        public ListNode ReverseList(ListNode head) {
            ListNode pre = null;
            ListNode now = head;
            ListNode aft = null;
            while(now != null){
                aft = now.next;
                now.next=pre;
                pre = now;
                now = aft;
            }
            return pre;
        }
    }
    Java

    第十七题 合并两个有序链表

    时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:641239
    本题知识点: 链表

     算法知识视频讲解

    题目描述

    输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
     
    题解:
    新建一个链表头。然后依次将两个链表中的元素加入即可,判断一下大小。
     
    参考代码:
    public class Solution {
        public ListNode Merge(ListNode l1,ListNode l2) {
             ListNode l3=new ListNode(0);
            ListNode l4=l3;
            while(l1!=null && l2!=null)
            {
                if(l1.val<=l2.val) 
                {
                    l3.next=l1;
                    l1=l1.next;
                }
                else 
                {
                    l3.next=l2;
                    l2=l2.next;
                }
                l3=l3.next;
            }
            if(l1!=null) l3.next=l1;
            else if(l2!=null) l3.next=l2;
            return l4.next;
        }
    }
    Java

    第十八题 树的子结构

    时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:617491
    本题知识点: 二叉树

     算法知识视频讲解

    题目描述

    输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
     
    题解:
    对于树B,要么和root本身相同,要么和root.left相同,要么和root.right相同。否则就不是树A的子结构。
    递归判断即可。
     
    参考代码:
    /**
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;
    
        public TreeNode(int val) {
            this.val = val;
    
        }
    
    }
    */
    public class Solution {
        
        public boolean IsSubtree(TreeNode a,TreeNode b)
        {
            if(b==null) return true;
            if(a==null) return false;
            if(a.val==b.val)
            {
                return IsSubtree(a.left,b.left) && IsSubtree(a.right,b.right);
            }
            else return false;
        }
        
        public boolean HasSubtree(TreeNode root1,TreeNode root2) 
        {
            if(root2==null||root1==null) return false;
            
            return IsSubtree(root1,root2)||HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);
        }
    }
    Java

    第十九题 二叉树镜像

    时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:355640
    本题知识点: 

     算法知识视频讲解

    题目描述

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

    输入描述:

    二叉树的镜像定义:源二叉树 
        	    8
        	   /  
        	  6   10
        	 /   / 
        	5  7 9 11
        	镜像二叉树
        	    8
        	   /  
        	  10   6
        	 /   / 
        	11 9 7  5

    题解:

    水题,递归将左右子树交换即可。

    参考代码:

    /**
    public class TreeNode {
        int val = 0;
        TreeNode left = null;
        TreeNode right = null;
    
        public TreeNode(int val) {
            this.val = val;
    
        }
    
    }
    */
    public class Solution {
        public void Mirror(TreeNode root) 
        {
            if(root==null) return ;
            TreeNode temp=root.left;
            root.left=root.right;
            root.right=temp;
            Mirror(root.left);
            Mirror(root.right);
        }
    }
    Java

    第二十题 顺时针打印矩阵

    时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:652806
    本题知识点: 数组

     算法知识视频讲解

    题目描述

    输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.
     
    题解:
    记录左右上下边界,然后依次输出(注意判断是否重合,左右,上下)。
    参考代码:
    class Solution {
    public:
        vector<int> printMatrix(vector<vector<int> > matrix) 
        {
            int row = matrix.size();
            if(row==0) return {};
            int col = matrix[0].size();
            vector<int> res;
            if (row == 0 || col == 0)  return res;
             
            // 定义四个关键变量,表示左上和右下的打印范围
            int left = 0, top = 0, right = col - 1, bottom = row - 1;
            while (left <= right && top <= bottom)
            {
                // left to right
                for (int i = left; i <= right; ++i)  res.push_back(matrix[top][i]);
                // top to bottom
                for (int i = top + 1; i <= bottom; ++i)  res.push_back(matrix[i][right]);
                // right to left
                if (top != bottom)
                for (int i = right - 1; i >= left; --i)  res.push_back(matrix[bottom][i]);
                // bottom to top
                if (left != right)
                for (int i = bottom - 1; i > top; --i)  res.push_back(matrix[i][left]);
                left++,top++,right--,bottom--;
            }
            return res;
        }
    };
    C++

    第二十一题 包含min函数的栈

    时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:381435
    本题知识点: 

     算法知识视频讲解

    题目描述

    定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
     
    题解:使用两个栈st,st2.st里面放元素,st2是个单调栈,保存当前栈st中的最小元素。
     
    参考代码:
    class Solution {
    public:
        stack<int> st,st2;
        
        void push(int value) 
        {
            st.push(value);
            if(st2.empty() || (value<st2.top()))
                st2.push(value);
        }
        void pop() 
        {
            if(!st.empty())
            {
                int val=st.top();
                st.pop();
                if(val==st2.top())
                    st2.pop();
            }
        }
        int top() 
        {
            if(!st.empty())
                return st.top();
        }
        int min() 
        {
            if(!st2.empty()) 
                return st2.top();
        }
    };
    C++

     第二十二题 栈的压入和弹出

    题目描述

    输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

     题解:我们模拟栈的压入,如果当前栈顶元素等于出栈的最前面的元素,则出栈,后移出栈数组的最前面元素,知道不相等,或则入栈数组元素用完。左后判断栈是否为空即可。

    参考代码:

    class Solution {
    public:
        bool IsPopOrder(vector<int> pushV,vector<int> popV) 
        {
            stack<int> st;
            int id=0;
            for(int i=0;i<popV.size();++i)
            {
                while(st.empty()||st.top()!=popV[i])
                {
                    st.push(pushV[id++]);
                    if(id>pushV.size())
                        return false;
                }
                st.pop();
            }
            if(st.empty()) return true;
            else return false;
        }
    };
    C++

     第二十三题 从上往下打印二叉树

    题目描述

    从上往下打印出二叉树的每个节点,同层节点从左至右打印。
     
    题解:用队列即可。
     
    参考代码:
    /*
    struct TreeNode {
        int val;
        struct TreeNode *left;
        struct TreeNode *right;
        TreeNode(int x) :
                val(x), left(NULL), right(NULL) {
        }
    };*/
    
    class Solution {
    public:
        vector<int> PrintFromTopToBottom(TreeNode* root) 
        {
            vector<int> ans;
            if(root==NULL) return ans;
            queue<TreeNode*> q;
        
            q.push(root);
            int cnt=1;
            while(!q.empty())
            {
                TreeNode* u=q.front();q.pop();
                ans.push_back(u->val);
                if(u->left) q.push(u->left);
                if(u->right) q.push(u->right);
            }
            return ans;
        }
    };
    C++

    第二十四题 二叉搜索树的后序遍历序列

     

    题目描述

    输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
     
    题解:二叉搜索树的性质:左子树的元素都比根小,右子树的元素都比根大。这样,知道最后一个元素一定是根,然后我们对每一层找到第一个比根大的元素,然后判断后面的是否都比根大,如果有比根小的,则返回false,否则继续判断左右子树,返回true,递归判断。
     
    参考代码:
    class Solution {
    public:
        bool VerifySquenceOfBST(vector<int> sequence) {
            return bst(sequence,0,sequence.size()-1);
        }
        bool bst(vector<int> sequence,int begin,int end)
        {
            if(sequence.empty()||begin>end)
                return false;
            int root=sequence[end];
            int i=begin;
            for(;i<end;++i)
                if(sequence[i]>root) break;
            for(int j=i;j<end;++j)
                if(sequence[j]<root) return false;
            bool left=true;
            if(i>begin)
                left=bst(sequence,begin,i-1);
            bool right=true;
            if(i<end-1)
                right=bst(sequence,i,end-1);
            return left&&right;
        }
    };
    C++
     
     
     
     
     
    未完待续~
     
  • 相关阅读:
    js代码的执行顺序及运算
    javascript讲解
    浏览器的差距
    标准流
    下拉列表
    单位
    滚动标签
    接着说一些有关排版的一些东西
    关于处理浏览器的兼容问题
    关于排版的技巧
  • 原文地址:https://www.cnblogs.com/csushl/p/11946380.html
Copyright © 2011-2022 走看看