一些常见算法题目

题目描述

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


class Solution
{
public:
	void push(int node) {

		stack1.push(node);
		
	}

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

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

题目描述

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


struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

void AddTreeNode(TreeNode* &pRoot, int ValCurrent, map<int, int> mapvid)
{
	TreeNode* pCurrent = NULL;
	if (pRoot == NULL)
	{
		pRoot = new TreeNode(ValCurrent);
		return;
	}
		
	if (mapvid[ValCurrent] > mapvid[pRoot->val])
	{
		if (pRoot->right == NULL)
		{
			pRoot->right = new TreeNode(ValCurrent);
		}
		else
		{
			AddTreeNode(pRoot->right, ValCurrent, mapvid);
		}
			
	}
	else
	{
		if (pRoot->left == NULL)
		{
			pRoot->left = new TreeNode(ValCurrent);
		}
		else
		{
			AddTreeNode(pRoot->left, ValCurrent, mapvid);
		}
	
	}
}

TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) 
{
	
	TreeNode* pRoot = NULL;
	TreeNode* pCurrent = pRoot;
	map<int, int> mapVinIndex;
	for (int i = 0; i < vin.size(); i++)
		mapVinIndex.insert(pair<int, int>(vin[i], i));

	int nMark = mapVinIndex[pre[0]];

	for (int j = 0; j < pre.size(); j++)
	{
		AddTreeNode(pRoot, pre[j], mapVinIndex);
	}

	return pRoot;
};

题目描述

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

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) 
    {
        vector<int> VectRet;
        ListNode*p = head;
        while(p != NULL)
        {
            VectRet.push_back(p->val);
            p = p->next;
        }
        reverse(VectRet.begin(),VectRet.end());
        return VectRet;
    }
};


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


int minNumberInRotateArray(vector<int> rotateArray)
{
	int imin = 0;
	int nMark1, nMark2;
	nMark1 = nMark2 = imin;
	if (rotateArray.size() > 0)
	{
		if (rotateArray.size() == 1)
			return rotateArray[0];
		if (rotateArray.size() > 1 && rotateArray[0] < rotateArray[rotateArray.size() - 1])
			return rotateArray[0];

		if (rotateArray.size() == 2)
		{
			imin = (rotateArray[0] > rotateArray[1] ? rotateArray[1] : rotateArray[0]);
			return imin;
		}
		
		nMark2 = rotateArray.size() / 2;
		if (nMark1 == nMark2)
		{
			imin = rotateArray[nMark1];
			return imin;
		}
		
		if (rotateArray[nMark1] > rotateArray[nMark2])
		{
			vector<int> vTemp(rotateArray.begin(), rotateArray.begin() + nMark2 - nMark1 + 1);
			imin = minNumberInRotateArray(vTemp);

		}
		else
		{
			vector<int> vTemp(rotateArray.begin() + nMark2 +1, rotateArray.end());
			imin = minNumberInRotateArray(vTemp);
		}
	}

	return imin;
}

题目描述

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

n<=39

int Fibonacci(int n) 
    {

        int f = 0, g = 1;
        while(n--) {
            g += f;
            f = g - f;
        }
        return f;

    }

题目描述

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

int jumpFloor(int number) {
        if (number <= 0) {
            return -1;
        } else if (number == 1) {
            return 1;
        } else if (number ==2) {
            return 2;
        } else {
            return  jumpFloor(number-1) + jumpFloor(number-2);
        }
    }

题目描述

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

参考解析

链接:https://www.nowcoder.com/questionTerminal/22243d016f6b47f2a6928b4313c85387
来源:牛客网
 

关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:

f(1) = 1

f(2) = f(2-1) + f(2-2)         //f(2-2) 表示2阶一次跳2阶的次数。

f(3) = f(3-1) + f(3-2) + f(3-3) 

...

f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n) 

说明: 

1)这里的f(n) 代表的是n个台阶有一次1,2,...n阶的 跳法数。

2)n = 1时,只有1种跳法,f(1) = 1

3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2) 

4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,

    那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)

    因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)

5) n = n时,会有n中跳的方式,1阶、2阶...n阶,得出结论:

    f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)

    

6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:

    f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)

    f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)

    可以得出:

    f(n) = 2*f(n-1)

    

7) 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为:

              | 1       ,(n=0 ) 

f(n) =     | 1       ,(n=1 )

              | 2*f(n-1),(n>=2)

int jumpFloorII(int number) 
{
        if(number <= 0)
            return 0;
        if(number == 1)
            return 1;
        
        return 2*jumpFloorII(number - 1);

}

题目描述

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

class Solution {
public:
     int  NumberOf1(int n) {
        int nBit = 0;
        int nCount = 8*sizeof(int);
        if (n & 1)
            nBit++;
        n = n >> 1;
        for (int i = 0; i < nCount - 1; i++)
        {
            if (n & 1)
                nBit++;
            n = n>>1;

        }
        return nBit;
     }
};

猜你喜欢

转载自blog.csdn.net/linlin003/article/details/81164766