编程之旅-Day26

目录

Day26-学习内容:

1.剑指Offer

面试题10:矩阵覆盖

面试题:数组在排序数组中出现的次数

面试题61:扑克牌中的顺子

 2.Leetcode

例1:二叉树下一个右指针

例2:二叉树的路径和


1.剑指Offer

面试题10:矩阵覆盖

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

思路:斐波那契数列

用归纳法归纳如下, 

(1)当 n < 1时,显然不需要用2*1块覆盖,按照题目提示应该返回 0。 

(2)当 n = 1时,只存在一种情况。 

(3)当 n = 2时,存在两种情况。 

代码:

class Solution {
public:
    int rectCover(int number) {
        int res=0;
        if(number<=0) return 0;
        else if(number==1||number==2) return number;
        else{
            res=rectCover(number-1)+rectCover(number-2);
            return res;
        }
    }
};

 

面试题:数组在排序数组中出现的次数

题目描述:统计一个数字在排序数组中出现的次数。

思路:顺序查找或是二分查找,需要充分利用排序数组的特点。

代码:

方法1:顺序查找

class Solution {
public:
    int GetNumberOfK(vector data ,int k) {
        int cnt=0;
        for(int i=0;idata[i]){
                i++;
            } 
            else if(k==data[i]){
                ++cnt;
                i++;
            }
            else if(k

方法2:利用C++ stl的二分查找

解析:equal_range函数治适用于已从小到大排好序的数组,返回一对迭代器,第一个迭代器指向所查找元素的第一次出现的位置,第二个迭代器指向所查找元素最后一次出现位置的后一个位置。

class Solution {
public:
    int GetNumberOfK(vector data ,int k) {
        auto resultPair=equal_range(data.begin(),data.end(),k);
        return resultPair.second-resultPair.first;
    }
};

 

面试题61:扑克牌中的顺子

题目描述:

LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。

思路:1.将数组排序 2.统计数组中0和间隔树 3.若间隔数小于等于0的个数,则数组连续否则不连续。

考察点:抽象建模的能力,将实际问题转化为程序语言表达的模型,通过排序、计数等步骤实现。

代码:

class Solution {
public:
    bool IsContinuous( vector numbers ) {
        if(numbers.empty()||numbers.size()<1) return false;
        
        int len=numbers.size();
        sort(numbers.begin(),numbers.end());
        int numberOfZero=0;
        int numberOfGap=0;
        
        for(int i=0;inumberOfZero)?false:true;       
    }
};

 

 2.Leetcode

例1:二叉树下一个右指针

A.完全二叉树

题目描述:

Given a binary tree 

    struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *next;
    }

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set toNULL. 

Initially, all next pointers are set toNULL. 

Note:

  • You may only use constant extra space.
  • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree, 

         1
       /  \
      2    3
     / \  / \
    4  5  6  7

After calling your function, the tree should look like: 

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL

思路:举例画图,递归实现

代码:

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(root==nullptr) return;
        if(root->left&&root->right){
            root->left->next=root->right;
        }
        if(root->next&&root->right){
            root->right->next=root->next->left;
        }
        connect(root->left);
        connect(root->right);
    }
};

B.任意二叉树

题目描述:

Follow up for problem "Populating Next Right Pointers in Each Node". 

What if the given tree could be any binary tree? Would your previous solution still work? 

Note:

  • You may only use constant extra space.

For example,
Given the following binary tree, 

         1
       /  \
      2    3
     / \    \
    4   5    7

After calling your function, the tree should look like: 

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \    \
    4-> 5 -> 7 -> NULL

思路:层序遍历

代码:

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
方法1:
class Solution {
public:
    void connect(TreeLinkNode *root) {
        while(root){
            TreeLinkNode dummy(-1),*prev;
            prev=&dummy;
            for(auto p=root;p;p=p->next){
                if(p->left){
                    prev->next=p->left;
                    prev=prev->next;
                }
                if(p->right){
                    prev->next=p->right;
                    prev=prev->next;
                }
            }
            root=dummy.next;            
        }
    }
};
方法2:

class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(root==NULL) return;
        queue que;
        que.push(root);
        while(!que.empty()){
            int n=que.size();
            for(int i=0;ileft){
                    que.push(tmp->left);
                }
                if(tmp->right){
                    que.push(tmp->right);
                }
                if(i!=n-1){
                    tmp->next=que.front();
                }
                else{
                    tmp->next=NULL;
                }
            }
            
        }
    }
};

 

例2:二叉树的路径和

A:判断路径是否存在

题目描述:

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. 

For example:
Given the below binary tree andsum = 22, 

              5
             / \
            4   8
           /   / \
          11  13  4
         /  \      \
        7    2      1

return true, as there exist a root-to-leaf path5->4->11->2which sum is 22. 

思路:递归

代码:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode *root, int sum) {
        if(root==NULL){
            return false;
        } 
        if(root->left==NULL&&root->right==NULL&&sum-root->val==0){
            return true;
        }
        return hasPathSum(root->left,sum-root->val)||hasPathSum(root->right,sum-root->val);
    }
};

B:输出满足条件的所有的路径

题目描述:

Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. 

For example:
Given the below binary tree andsum = 22, 

              5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1

return 

[
   [5,4,11,2],
   [5,8,4,5]
]

代码:

class Solution {
public:
    vector > pathSum(TreeNode *root, int sum) {
        vector > res;
        vector path;
        pathSumCore(root,sum,path,res);
        return res;
    }
    void pathSumCore(TreeNode *root, int sum, vector path, vector > &res){ //注意path不要加&,才能递归,相当于自动出栈
        if(root==NULL) return;
        path.push_back(root->val);
        if(root->left==NULL&&root->right==NULL&&sum-root->val==0){
             res.push_back(path);
        }
        pathSumCore(root->left,sum-root->val,path,res);
        pathSumCore(root->right,sum-root->val,path,res);
    }                    
};

 

 

你可能感兴趣的:(计算机,编程,算法,数据结构,算法,数据结构)