algorithm 题集八 (18.03.25)

标签: cpp algorithm
17人阅读 评论(0) 收藏 举报
分类:

本文一共12题,均来自《剑指offer》,不复杂。在平时的练习中收集了部分组合而成。

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

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

(3)用两个队列实现一个栈。完成栈的Push,Pop,top等操作。

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

(5)大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39。(斐波那契数列:1、1、2、3、5、8、13、21、34、…… 在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2))

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

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

(8)链表反转。

(9)输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

(10)输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

(11)输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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.

(12)定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。


思路:
(1)递归查找顶点。
(2)一个栈专门负责进,另一个栈专门负责出。
(3)一个队列负责主存储,另一个队列负责临时存储(用于辅助实现pop操作)。
(4)第一种思路:暴力,直接从后面向前遍历,直到找到最小值。第二种思路:由于原始数组是非递减数组,那么旋转后的数组后面第二部分的任意一个元素一定是小于等于前面任何一个元素。然后,我们可以使用二分不断缩小比较的空间。
思路二的大致过程:
先确定left = 0, right = size -1。二分得到mid = (left+right)>>1
如果array[mid] > array[left], 那么array[mid]属于第一部分,left = mid
如果array[mid] < array[left],那么array[mid]属于第二部分,right = mid
如果array[mid] == array[left],那么有可能是3 1 3 3 3,也有可能是 3 3 3 1 3。两种情况均满足条件。故无法判断,直接暴力搜索。
(5)个人觉得,最快的方法是在构造函数中打表,然后解答函数直接输出array[n]。
(6)动态规划问题,当青蛙跳到第n级,可供选择的路径共有F(n-1) + F[n-2]。所以递推式就是菲波那切数列。
(7)寻找规律:

f[1] = 1
f[2] = f[1]+1 = 2
f[3] = f[1]+f[2]+1 = 4
f[4] = f[1]+f[2]+f[3]+1 = 8
f[5] = f[1]+f[2]+f[3]+f[4]+1 = 16
==> f[n] = 2^(n-1)

(8)放两个指针记录遍历指针的前节点和后节点。然后改变遍历指针的next指向。一趟遍历完整就完成了任务。

    ListNode* ReverseList(ListNode* pHead) {
        ListNode* next = NULL;
        ListNode* pre = NULL;
        while(pHead){
            next = pHead->next;
            pHead->next = pre;
            pre = pHead;
            pHead = next;
        }
        return pre;
    }

(9)将麻烦事交给计算机,我们指出关键步骤即可。递归无敌!

class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1 == NULL) return pHead2;
        else if(pHead2 == NULL) return pHead1;
        else {
            if(pHead1->val <= pHead2->val){
                pHead1->next = Merge(pHead1->next,pHead2);
                return pHead1;
            }
            else {
                pHead2->next = Merge(pHead1,pHead2->next);
                return pHead2;
            }
        }
    }
};

(10)首先需要确定满足“相同(子结构)”
然后左右子树递归查找。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    bool isSubtree(TreeNode* pRoot1, TreeNode* pRoot2) {
        if(pRoot2 == NULL) return true;
        if(pRoot1 == NULL) return false;
        if(pRoot1->val == pRoot2->val){
            return isSubtree(pRoot1->left, pRoot2->left) && isSubtree(pRoot1->right, pRoot2->right);
        }
        else  return false;
    }
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
        if(pRoot1 == NULL || pRoot2 == NULL) return false;
        return isSubtree(pRoot1, pRoot2) || \
                HasSubtree(pRoot1->left,pRoot2) || \
                HasSubtree(pRoot1->right,pRoot2); 
    }
};

(11)我的方案:找到需要打印的圈数和左上顶点,打印外围数字。这样由外向内循环下去。
然后,看到其他网友的解法。有一个非常的巧妙:打印第一行,然后删除此行,接着逆时针旋转90度构造新的矩形。重新这个步骤。

(12)添加一个辅助栈,用于每次push元素压入新的最小元素,每次pop元素弹出栈顶元素,min函数直接查询辅助栈的栈顶元素即可。
当然,我没想那么多(呵呵),直接去暴力实现了。

class Solution {
    int *data;
    unsigned int length;
    unsigned int size;

public:
    Solution(){
        length = 0;
        size = 0;
        data = NULL;
    }
    ~Solution(){
        length = 0;
        size = 0;
        delete data;
        data = NULL;
    }
    unsigned int _align_it(unsigned int newSize){
        return newSize+(sizeof(int)-1) & ~(sizeof(int)-1);
    }
    unsigned int recommend(unsigned int newSize){
        return std::max(2*length, _align_it(newSize));
    }
    void reserve(unsigned int size){
        if(size > length) {
            int old_length = length;
            int *old_data = data;
            length = recommend(size);
            data = new int[length];
            for(int i=0; i<old_length; i++){
                data[i] = old_data[i];
            }
            delete old_data;
        }
    }
    void push(int value) {
        reserve(++size);
        data[size-1] = value;
    }
    void pop() {
        if(size == 0){
            return ;
        }
        size--;
    }
    int top() {
        try{
            if(size == 0) throw "there is no number in data.";
            return data[size-1];
        }
        catch(char *str){
            cout<<str<<endl;
            return -1;
        }
    }
    int min() {
        try{
            if(length == 0) throw "length is equal to zero";
            int minVal = data[0];
            for(int i=1;i<size;i++){
                minVal = minVal<data[i]?minVal:data[i];
            }
            return minVal;
        }
        catch(char *str){
            cout<<str<<endl;
            return -1;
        }
    }
};
查看评论

poj1740-楼教主所谓的男人八题之一

*题目大意: * 对于n堆石子,每堆若干个,两人轮流操作,每次操作分两步, * 第一步从某堆中去掉至少一个,第二步(可省略)把该堆剩余 * 石子的一部分分给其它的某些堆。最后谁无子可取即输。 ...
  • zhang20072844
  • zhang20072844
  • 2012-10-25 23:40:27
  • 4329

楼教主男人必解八题之 Coins 解题报告

楼教主男人必解八题之 Coins 解题报告 题目详见http://acm.hdu.edu.cn/showproblem.php?pid=2844 这个题目和POJ1742是一个题目,也是楼教主的男人...
  • sustliangbo
  • sustliangbo
  • 2013-08-04 22:20:52
  • 3929

POJ 1741 Tree(树分治|ltc男人八题)

LTC男人八题
  • u014664226
  • u014664226
  • 2015-08-12 00:45:39
  • 878

楼天成的男人八题+ACM\做男人不容易系列是男人就过8题.ppt

  • 2011年08月19日 19:41
  • 510KB
  • 下载

Eight-point algorithm

转载地址:https://en.wikipedia.org/wiki/Eight-point_algorithm 在 2D-2D VO中,当已知内参矩阵K,需要求解 本征矩阵 essential m...
  • u011722133
  • u011722133
  • 2017-06-15 14:58:49
  • 275

楼天城之做男人就过八道题(第一题…

关于楼教主的第一题,感觉最费时间的还是高精度的实现。实现一万位以上整数基本运算的万进制高精度模版就写了快一天(题目里用到大概也有几百位吧),只能说太容易出错了,得不断地调试修改。题目源地址是北大poj...
  • xiefubao
  • xiefubao
  • 2014-01-16 16:38:27
  • 2604

是男人就过8题!楼教主出题,请接招!

近日,前百度首席架构师(T11)彭军联手百度史上最年轻的 T10 楼天城共同创立的 Pony.AI 在网络上发起了一项挑战赛。这项名为“是男人就过 8 题”的挑战赛,瞬间点燃了笔者的斗志。 首先...
  • dQCFKyQDXYm3F8rB0
  • dQCFKyQDXYm3F8rB0
  • 2018-03-26 19:26:07
  • 2403

POJ 1742 Coins(多重背包变型,楼教主男人八题)

Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 34853   Accepte...
  • hhu1506010220
  • hhu1506010220
  • 2016-08-31 17:04:22
  • 407

楼天城教主的男人八题和题解

  • 2014年09月29日 13:12
  • 204KB
  • 下载

男人八题系列

男人之路。。。还差最后一题,敬请期待~
  • u011383868
  • u011383868
  • 2013-07-20 20:27:58
  • 1536
    个人资料
    持之以恒
    等级:
    访问量: 37万+
    积分: 9445
    排名: 2418
    我的链接
    最新评论