剑桥offer系列(1~10)

1.题目描述

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:从左下开始,小,往上,大,往右。
class Solution {
public:
    bool Find(vector<vector<int> > array,int target) {
        
        if(array.size()==0)return false;
        int r=array.size();
        int c=array[0].size();
        int i=r-1,j=0;
        
        while(i<r&&i>-1&&j<c&&j>-1){
            
            if(array[i][j] == target)return true;
            if(array[i][j]>target){
                i--;
            }else{
                j++;
            }
        }
        return false;
        
    }
};
View Code

 

2.题目描述

请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
思路:替换空格。
//length为牛客系统规定字符串输出的最大长度,固定为一个常数
class Solution {
public:
    void replaceSpace(char *str,int length) {
    int i = 0;
    int j = 0;
    int nSpace = 0;
    char *pStr = NULL;
    pStr = (char*)malloc(sizeof(char)*length * 3);
    for (i = 0, j = 0; i<length; i++, j++)
    {
        if (' ' == str[i])
        {
            pStr[j] = '\%';
            pStr[++j] = '2';
            pStr[++j] = '0';
        }
        else
        {
            pStr[j] = str[i];
        }

    }
    for( i=0;i<j;i++ )
    {
      str[i] = pStr[i];
    }

    free(pStr);
    pStr = NULL;
}
};
View Code

3.题目描述

输入一个链表,从尾到头打印链表每个节点的值。 
思路:使用vector去接,然后调用逆序算法reverse(v.begin(),v.end());
/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
    vector<int> printListFromTailToHead(struct ListNode* head) {
        
        struct ListNode* tmp = head;
        vector<int>v;
        while(tmp != NULL){
            v.push_back(tmp->val);
            tmp = tmp->next;
        }
        reverse(v.begin(),v.end());
        return v;
    }
};
View Code

 

4.题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
 
 思路:通过前序和中序,找到根,然后递归调用。
/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {
        int in_size = in.size();

        if (in_size == 0)
            return NULL;
        vector<int> pre_left, pre_right, in_left, in_right;
        int val = pre[0];
        TreeNode* node = new TreeNode(val);//root node is the first element in pre
        int p = 0;
        for (; p < in_size; ++p){
            if (in[p] == val) //Find the root position in in 
                break;
        }
        for (int i = 0; i < in_size; ++i){
            if (i < p){
                in_left.push_back(in[i]);//Construct the left pre and in 
                pre_left.push_back(pre[i + 1]);
            }
            else if (i > p){
                in_right.push_back(in[i]);//Construct the right pre and in 
                pre_right.push_back(pre[i]);
            }
        }
        node->left = reConstructBinaryTree(pre_left, in_left);
        node->right = reConstructBinaryTree(pre_right, in_right);
        return node;
    }  
};
View Code

5.题目描述

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
思路:数据经过入和出,经过2个栈可以实现队列。
class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
      
        if(stack2.empty()){
            while(!stack1.empty()){
                stack2.push(stack1.top());
                stack1.pop();
            }
        }
        int node = stack2.top();
        stack2.pop();
        return node;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};
View Code

6.题目描述

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路:找到突变点,下一个就是所要的值。
class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        int i=0;
        int  len = rotateArray.size();
        if(len==0)return 0;
          if(len==1)return rotateArray[0];
        while(i<len-1){
            if(rotateArray[i]<=rotateArray[i+1]){
                i++;
            }else{
                break;
            }
        }
       return   rotateArray[i+1];
    }
};
View Code
    int minNumberInRotateArray(vector<int> rotateArray) {
        int len = rotateArray.size();
        if(len == 0)
            return 0;
        if(len == 1)
            return rotateArray[0];
        int l=0;int r=len-1;
        while(l<r){
            int m= (l+r)/2;
            if(rotateArray[m] >= rotateArray[r] ){
                l=m+1;
            }else{
                r=m;
            }
        }
        return rotateArray[l];
    }
View Code

 

7.题目描述

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39
斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)
class Solution {
public:
    int Fibonacci(int n) {
        if(n == 0)
            return 0;
        if(n == 1)
            return 1;
        int numfn1 = 0, numfn2 = 1;
        int currentnum;
        for(int i=2; i<=n; ++i) {
            currentnum = numfn1+numfn2;
            numfn1 = numfn2;
            numfn2 = currentnum;
        }
        return currentnum;
    }
};
View Code

8.题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路:同第7题
class Solution {
public:
    int jumpFloor(int number) {
        if (number == 1)return 1;
        if (number == 2)return 2;
        int val;
        int num1=1;
        int num2=2;
        
        while(number-->2){
            val = num1+num2;
            num1 = num2;
            num2 = val;
        }
        return val;
    }
};
View Code

9.题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路:
  a[n]=a[n-1]+a[n-2]+......+a[1];..........................①
  a[n-1]=        a[n-2]+......+a[1];..........................②
  两式相减可知:a[n]=2*a[n-1];
class Solution {
public:
    int jumpFloorII(int number) {
        int f=1,fn=1;
        for(int i=2;i<=number;i++){
            fn=2*f;
            f=fn;
        }
        return fn;
    }
};
View Code

10.题目描述

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
 思路:同7
class Solution {
public:
    int rectCover(int number) {
        if(number==1)return 1;
        if(number==2)return 2;
        int n1=1,n2=2,val=0;
        for(int i=2;i<number;i++){
            val = n1 + n2;
            n1=n2;
            n2=val;
        }
        return val;
    }
};
View Code

 

 
 
posted @ 2016-11-09 18:47  于光远  阅读(226)  评论(0编辑  收藏  举报