1. 程式人生 > >整數數組的組合問題

整數數組的組合問題

部分 大學 分解 clas n) 筆試題 ati return total

2015年9月16日,美團南京站南京郵電大學筆試題目之中的一個。

大致的題意是這種:

有一個元素各不同樣的整數數組。輸入元素的全部組合。長度由大到小。比如:[1, 2, 3, 4],依次輸出1234。123。134,234。12,13,14,23,24。1,2,3。4


思路:

1、設輸出的組合的長度為m(m<=n)

2、把數組分為兩個部分:第一個數和後面的m-1個數

3、假設組合裏包括第一個數,則下一步在剩余的n-1個數裏選取m-1個字符。假設不包括第一個數。則下一步在剩余的m-1個數裏面選取m個數

把n個數中求長度為m的組合分解成:求n-1個數裏面長度為m-1個數的組合,以及從n-1個數裏面求長度為m的組合的兩個子問題。用遞歸解決。

另外,能夠使用vector或者statck數據結構存儲當前的結果。本文採用的是vector。

// totalLen:數組長度,curIndex:遞歸過程中的“第一個”元素在數組中的位置,
// lengthLeft:組合中須要加入的元素個數,res:存放當前組合的元素
void combine(int *a, int totalLen, int curIndex, int lengthLeft, vector<int> &res)
{
	if (lengthLeft == 0){
		vector<int>::const_iterator iter = res.begin();
		for (; iter != res.end(); ++iter)
			cout << *iter;
		cout << "\n";
		return;
	}

	// 若遞歸過程中希望作為“第一個元素”的位置已超過數組的長度,則退出
	if (curIndex == totalLen) 
		return;

	res.push_back(a[curIndex]);
	combine(a, totalLen, curIndex + 1, lengthLeft - 1, res);
	res.pop_back();
	combine(a, totalLen, curIndex + 1, lengthLeft, res);
}

void combinationOfInt(int *a, int len)
{
	if (!a)
		return;
	vector<int> res;
	for (int i = len; i >= 1; --i)
		combine(a, len, 0, i, res);
}

int main(void)
{
	int a[] = { 1, 2, 3, 4, 5 };
	combinationOfInt(a, 5);

	return 0;
}


整數數組的組合問題