最近換了工作,房子到期了又到處去看房子装诡,加上周末還要上課做作業(yè),感覺好累践盼,精神總不容易集中鸦采,導致本周的題目斷斷續(xù)續(xù)弄了好幾天才做出來,看來還是要好好休息啊咕幻。本周題目難度級別'Medium'渔伯,使用語言C
題目:本周題目很簡單,就是給你一組不重復的數肄程,要求返回這組數的全排列集合锣吼。例如給你[1,2,3],你要返回的是[[1,2,3],[1,3,2],[2,3,1],[2,1,3],[3,1,2],[3,2,1]]
思路:這個我想了很多选浑,也嘗試了很多,中間走的坑我就不說了玄叠,直接講最后的結果吧古徒,我是用的迭代,一列一列的寫读恃,寫完一列隧膘,下一列繼續(xù)按規(guī)律寫,下圖展示的是[1,2,3,4]的全排列(一行代表一組)狐粱,以下圖為例舀寓,我們可以看出幾個規(guī)律:
1.全排列組合的個數就是給定的數的階層。(如下圖4!=24個)
2.倒數第三列以前就是給定的數的循環(huán)(圖中有顏色的部分)肌蜻。
3.沒有了互墓,用前兩條就夠了。
[1,2,3,4]的全排列
然后擼起袖子看代碼(從注釋下面的permute函數看起):
void newPermute(int* nums, int numsSize, int row, int col, int** result, int count) {
if (numsSize == 1) {
//只有一位
result[row][col] = nums[0];
}else {
//還有好多位蒋搜,需要繼續(xù)迭代
int newCount = numsSize-1;
int divisor = count / numsSize;
//遍歷數組
for(int i = 0; i < numsSize; i++){
//賦值(有顏色的那部分)
for (int j = 0;j < divisor; j++) {
result[i*divisor+row+j][col] = nums[I];
}
//構造出新的需要全排列的集合
int* tempResult = malloc(sizeof(int) * newCount);
for (int k = 0; k < newCount; k++) {
if (k < i) {
tempResult[k] = nums[k];
}else {
tempResult[k] = nums[k+1];
}
}
//調用遞歸(新的需要排列組合的集合篡撵,集合的個數,從第幾行開始豆挽,從第幾列開始育谬,結果容器,總長度)
newPermute(tempResult, newCount, i*divisor+row, col+1, result, divisor);
}
}
}
/**
* Return an array of arrays of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int** permute(int* nums, int numsSize, int* returnSize) {
//先利用第一條算出n帮哈!
*returnSize = 1;
for (int i = 2; i <= numsSize; i++) {
*returnSize *= I;
}
//根據個數開辟空間膛檀,初始化容器
int** result = malloc(sizeof(int*) * *returnSize);
for (int i = 0; i < *returnSize; i++) {
result[i] = malloc(sizeof(int) * numsSize);
}
//調用遞歸(參數含義依次是:新的需要排列組合的集合,集合的個數娘侍,從第幾行開始咖刃,從第幾列開始,結果容器憾筏,處理個數)
newPermute(nums, numsSize, 0, 0, result, *returnSize);
return result;
}
效率一般嚎杨,然后和小伙伴們聊的時候發(fā)現C還是挺麻煩的,主要麻煩在需要處理內存氧腰,要開辟空間枫浙、要初始化,二維指針開辟完空間還要給一維空間開辟指針古拴,分別初始化箩帚。。斤富。