1. 程式人生 > >一些常見演算法題目

一些常見演算法題目

題目描述

用兩個棧來實現一個佇列,完成佇列的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;
     }
};