牛客题霸 C++题解/答案 共五篇(跳台阶,合并有序链表,用两个栈实现队列,括号序列,两个链表的第一个公共结点)

跳台阶

题目描述

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

题解:

递归的入门题
如果只剩一个台阶,只有一种跳法(一步)
如果还剩两个台阶,有两种跳法(两个一步或者一个两步)
当有n个台阶,可以转化成n-1和n-2两种情况的和
依次递归下去,边界就是n = = 1和n = = 2

代码:

class Solution {
public:
    int jumpFloor(int number) {
        if(number==1)return 1;
        else if(number==2)return 2;
        else return jumpFloor(number-1)+jumpFloor(number-2);
    }
};

合并有序链表

题目描述

将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的。

题解:

首先判断l1和l2是否为空
然后依次比较l1和l2的值,然后存到新的链表里,当有一方全部结束时,另一部分剩下的所有直接连在链表后面

代码:

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param l1 ListNode类 
     * @param l2 ListNode类 
     * @return ListNode类
     */
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        // write code here
        if(l1==NULL&&l2==NULL)return NULL;
        else if(l2==NULL)return l1;
        else if(l1==NULL)return l2;
        ListNode *head = new ListNode(0);
        ListNode *tail=head;
        while(l1!=NULL&&l2!=NULL)
        {
            if(l1->val<=l2->val)
            {
                tail->next=l1;
                l1=l1->next;
            }
            else 
            {
                tail->next=l2;
                l2=l2->next;
             }
            tail = tail->next;
        }
        if(l1==NULL)tail->next=l2;
        else tail->next=l1;
        return head->next;
        
    }
};

用两个栈实现队列

题目描述

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

题解:

我们都知道栈的性质是先进后出,队列是先进先出
我们用两个栈来模拟出队列
可以先用一个栈来存数,当要输出时,最上面的是最晚进栈的,我们将所有数存到另一个栈内,这样就使得第二个栈的顶部是最早输入的数,就可以实现先进先出

代码:

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 num = stack2.top();
        stack2.pop();
        return num;
    }

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

括号序列

题目描述

给出一个仅包含字符’(’,’)’,’{’,’}’,’[‘和’]’,的字符串,判断给出的字符串是否是合法的括号序列
括号必须以正确的顺序关闭,"()“和”()[]{}“都是合法的括号序列,但”(]“和”([)]"不合法。

题解:

用栈来做
用栈来存每个符号的左边,当出现符号右边时,看栈的顶部是否为该符号的左边,如果不能匹配则返回0,能匹配则将栈顶pop
全部结束时栈应该是空的,否则返回0
注意:题目给的数据有可能会先输入符号的右部分,所以当栈为空时也应该压入字符

if(s[i]=='('||s[i]=='{'||s[i]=='['||q.empty())

没有这个q.empty()会导致段错误

代码:

class Solution {
public:
    /**
     * 
     * @param s string字符串 
     * @return bool布尔型
     */
    bool isValid(string s) {
        // write code here
        stack<char>q;
        for(int i=0;i<s.length();i++)
        {
            if(s[i]=='('||s[i]=='{'||s[i]=='['||q.empty())
            {
                q.push(s[i]);
                continue;
            }
            if(s[i]==')'&&q.top()!='(')return false;
            else if(s[i]=='}'&&q.top()!='{')return false;
            else if(s[i]==']'&&q.top()!='[')return false;
            else if(q.empty())return false;
            q.pop();
        }
        if(q.empty())return true;
        else return false;
    }
};

两个链表的第一个公共结点

题目描述

输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)

题解:

可以理解成两个数组找第一个公共节点
就是两个for循环,从第一个数组的第一位开始与第二个数组的第一位开始判断是否相同,然后比第二个数组的第二位,一直这样进行
但这里是链表,所以一开始没跑完第二个链表,就要重新回到起点
list2 = pHead2;
详细看代码

代码:

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
        if(!pHead1 || !pHead2) return NULL;
    ListNode *list1,*list2;
    list1 = pHead1;
    list2 = pHead2;
    
    while(list1 != NULL)
    {
        list2 = pHead2;
        while(list2 !=NULL)
        {
            if(list1 == list2)
            {
                return list1;
                break;
            }
            else
            {
                list2 = list2->next;
            }
        }
        
        list1 = list1->next;
    }
    
    return list1;
    }
};
posted @ 2020-11-04 19:33  回归梦想  阅读(115)  评论(0编辑  收藏  举报