真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

代碼隨想錄算法訓(xùn)練營第十三天|n皇后&數(shù)獨(dú)老經(jīng)典了-創(chuàng)新互聯(lián)

Leecode 90. 子集 II

鏈接:https://leetcode.cn/problems/subsets-ii/

創(chuàng)新互聯(lián)公司是一家專注于做網(wǎng)站、成都做網(wǎng)站與策劃設(shè)計(jì),中原網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:中原等地區(qū)。中原做網(wǎng)站價格咨詢:028-86922220

那么這道題和上一道題有什么區(qū)別呢?

沒什么區(qū)別,就是僅僅多了重復(fù)元素而已,那怎么搞?

實(shí)際上[1,4,4]和[4,1,4]是同一個子集,所以就還要去重

不急,在遞歸的下面加上這句話

while(i+1< nums.size() && vec[vec.size()-1] == nums[i+1]

在pop元素之前,如果我們發(fā)現(xiàn)要pop的元素和下一個push進(jìn)來的元素一毛一樣,那么我們就讓i++

class Solution {public:
    vector>ans;
    vectorvec;
    void recursion(vector& nums,int k,int step)
    {// 元素收集滿了,記錄當(dāng)前vec然后return
        if(vec.size() == k)
        {ans.push_back(vec);
            return;
        }
        for(int i = step;ivec.push_back(nums[i]);
            recursion(nums,k,i + 1); // 是取搜下一個元素了
            while(i+1< nums.size() && vec[vec.size()-1] == nums[i+1]) i++; // 那么就跳過重復(fù)的數(shù)據(jù)唄
            vec.pop_back();
        }
    }
    vector>subsetsWithDup(vector& nums) 
    {sort(nums.begin(),nums.end());
        for(int i = 1; i< nums.size() ;i++) 
        {vec.clear();
            recursion(nums,i,0); 
        }
        //vector>res (ans.begin(),ans.end());
        ans.push_back({});
        ans.push_back(nums);
        return ans;
    }
};
Leecode 491. 遞增子序列

鏈接:https://leetcode.cn/problems/increasing-subsequences/description/

注意,這個題目比較特別

因?yàn)橐筝敵鲞f增序列,因此是不可以排序的,而我們之前推崇的辦法

while(i + 1< nums.size() && nums[i+1] == vec[vec.size()-1]) i++;

也僅僅在排好序的數(shù)組上管用

所以我們需要重新思考去重的方式——set

同時因?yàn)轭}目要求遞增,所以需要在push之前判斷當(dāng)前元素是不是比vector中的最后一個元素大

class Solution {public:
    set>ans;
    vectorvec;
    void recursion(vector& nums,int k,int step)
    {if(vec.size() == k)
        {ans.insert(vec);
            return;
        }
        for(int i=step;iif(!vec.empty() && nums[i] >= vec[vec.size()-1] || vec.empty()) // 如果滿足遞增,再把元素給push進(jìn)來
            {vec.push_back(nums[i]);
                recursion(nums,k,i + 1);
                //while(i + 1< nums.size() && nums[i+1] == vec[vec.size()-1]) i++; // 不能排序這個辦法基本上就死了,所以需要set
                vec.pop_back();
            }
        }
    }
    vector>findSubsequences(vector& nums) {//sort(nums.begin(),nums.end()); // 注意這個題目是不允許排序的
        for(int i=2;i<=nums.size();i++)
        {vec.clear();
            recursion(nums,i,0);
        }
        vector>res(ans.begin(),ans.end());
        return res;
    }
};
Leecode 46. 全排列

鏈接:https://leetcode.cn/problems/permutations/

確實(shí)是需要used數(shù)組了,記錄當(dāng)前哪些元素用過哪些元素沒有用過

值得注意的一點(diǎn)是:used中的索引值需要是當(dāng)前元素在nums中的索引而不能是當(dāng)前元素的值,因?yàn)楫?dāng)前元素可能是負(fù)值···

class Solution {public:
    // 想返回全排列最好的辦法就是用數(shù)組記重了
    vector>res;
    vectorvec;
    int used[100];
    void recurison(vector& nums)
    {if(vec.size() == nums.size()) 
        {res.push_back(vec);
            return;
        }
        for(int i = 0;iif(!used[i]) // 最好是記錄索引而不是值,因?yàn)橹涤锌赡苁秦?fù)的
            {vec.push_back(nums[i]);
                used[i] = 1;
                recurison(nums);
                used[i] = 0;
                vec.pop_back();
            }
        }
    }
    vector>permute(vector& nums) {recurison(nums);
        return res;
    }
};
Leecode 47. 全排列 II

鏈接:https://leetcode.cn/problems/permutations-ii/

加個set去重咯,沒有新意~

class Solution {public:
    set>ans;
    vectorvec;
    int used[100];
    void recurison(vector& nums)
    {if(vec.size() == nums.size()) 
        {ans.insert(vec);
            return;
        }
        for(int i = 0;iif(!used[i]) // 最好是記錄索引而不是值,因?yàn)橹涤锌赡苁秦?fù)的
            {vec.push_back(nums[i]);
                used[i] = 1;
                recurison(nums);
                used[i] = 0;
                vec.pop_back();
            }
        }
    }
    vector>permuteUnique(vector& nums) {recurison(nums);
        vector>res(ans.begin(),ans.end());
        return res;
    }
};
Leecode 332. 重新安排行程

鏈接:https://leetcode.cn/problems/reconstruct-itinerary/

孫哥講的真很好,很細(xì)

class Solution {unordered_map>targets;
    bool backtracking(int ticketNum, vector& result) {if (result.size() == ticketNum + 1) {return true;
        }
        for (pair& target : targets[result[result.size() - 1]]) 
        {if (target.second >0 ) 
            {// 記錄到達(dá)機(jī)場是否飛過了
                result.push_back(target.first);
                target.second--;
                if (backtracking(ticketNum, result)) return true;
                result.pop_back();
                target.second++;
            }
        }
        return false;
    }
    public:
        vectorfindItinerary(vector>& tickets) 
        {targets.clear();
            vectorresult;
            for (const vector& vec : tickets) 
            {targets[vec[0]][vec[1]]++; // 記錄映射關(guān)系
            }
            result.push_back("JFK"); // 起始機(jī)場
            backtracking(tickets.size(), result);
            return result;
        }
};
Leecode 51. N 皇后

鏈接:https://leetcode.cn/problems/n-queens/

經(jīng)典練手題

// 區(qū)區(qū)n皇后是困難???
class Solution {public:
    vector>res;
    // 首先我們枚舉行,從左到右,看行上的哪個元素可以放置Q
    bool check(int n,int row,int column,vector&test)
    {// [row,column]
        // 若是在row這行有元素,我們就直接return false
        for(int i=0;iif(test[i][column] == 'Q') return false;
            if(row - i >= 0 && column + iif(test[row - i][column + i] == 'Q') return false;}
            if(row - i >= 0 && column - i >=0) {if(test[row - i][column - i] == 'Q') return false;}
        }
        return true;c    
    }
    void recursion(int n,int step,vector&test) // 直接修改test數(shù)組
    {// 如果當(dāng)前枚舉的行數(shù)已經(jīng)超過了n,那么我們直接就記錄當(dāng)前答案然后return
        if(step >n-1) 
        {res.push_back(test);
            return;
        }
        for(int i=0;iif(check(n,step,i,test)) // 如果當(dāng)前位置是合法的
            {test[step][i] = 'Q';
                recursion(n,step + 1,test);
                test[step][i] = '.';
            }
        }
    }
    vector>solveNQueens(int n) // 此處的n給的是棋盤的大小 
    {// 首先需要初始化數(shù)組,答案是用三維數(shù)組裝填的
        vectortest(n , string(n,'.')); // 剛開始我們將數(shù)組全部都用'.'裝填之
        recursion(n,0,test);
        return res;
    }
};
Leecode 37. 解數(shù)獨(dú)

經(jīng)典練手題2,主要看細(xì)不細(xì)

首先我們考慮如何遞歸的問題:按理說是9*9的方格逐個位置搜索,那用for循環(huán)枚舉位置不是有點(diǎn)多余?因?yàn)橐苿油τ幸?guī)律的,所以我們這里就沒有用兩層for循環(huán)去枚舉位置(加上枚舉數(shù)字就有三層循環(huán)了),我們只要枚舉當(dāng)前位置需要填入的值就OK了

至于行數(shù)和列數(shù),一般都是遞歸到當(dāng)前行的下一列,只有當(dāng)前行所有列全都遍歷完畢才會去下一行,根據(jù)這個規(guī)律就能得到下一次遞歸的位置在哪

還有一個需要注意的點(diǎn):數(shù)獨(dú)數(shù)組本來就是有值的,并且我們在填充數(shù)獨(dú)的過程中是不可以改變原來數(shù)獨(dú)中的值的,因此我們在遞歸的過程中發(fā)現(xiàn)當(dāng)前位置若是有值,就直接遞歸到下一層。并且,從此處回溯是不合理的,所以在遞歸操作的后面直接加上return避免此處回溯進(jìn)入到后面的for循環(huán),同時也提高了效率

除此之外,我設(shè)計(jì)了一個check函數(shù),用來判斷在當(dāng)前位置填入num是否合法——還是為了提高效率,開始的時候我們就得到了不完全的數(shù)獨(dú)數(shù)組,為了避免重復(fù)值出現(xiàn)在“同一行”,“同一列”,“同一個3 * 3矩陣”中,我們還要定義三個數(shù)組用來記錄“當(dāng)前行”,“當(dāng)前列”,“當(dāng)前的3 * 3矩陣中哪些數(shù)字被使用過

最后還有一個需要注意的點(diǎn):數(shù)獨(dú)填充完畢后是要return的,但是真的return回來所有被填充的數(shù)字又會變成’.',所以在填充完畢后,我們定義標(biāo)志位flag為1,并且在回溯的時候加上判斷——只有在標(biāo)志位不為1的時候才回溯,這樣我們return回來的數(shù)組就是完整的

class Solution {public:
    int rows[10][10];
    int cols[10][10];
    int cell[10][10][10];
    int flag = 0;
    // 首先先遍歷一遍數(shù)獨(dú),將其中都是1的位置全都置為1,表示這個元素已經(jīng)被使用過了
bool check(int row, int col, vector>& board, int num)
{// 若是行中列中包括cell中都沒有出現(xiàn)過這個元素,那么return true
	if (rows[row][num]) return false;
	if (cols[col][num]) return false;
	if (cell[row/3][col/3][num]) return false;
	return true;
}
void recursion(vector>& board, int row, int col)
{if (flag) return;
	if (col == 9)        {col = 0; row += 1; }
	if (row == 9 && col == 0) // 已經(jīng)將數(shù)組填充完畢
	{flag = 1;
		return;
	}
	if (board[row][col]!='.') {recursion(board, row, col + 1); return; } // 如果當(dāng)前有元素,直接跳過,并且不允許回溯,直接return

	// 你覺得需要用for循環(huán)枚舉位置嗎,是不是所有順序都是固定的
	for (int num = 1; num<= 9; num++) // num是當(dāng)前準(zhǔn)備填充的元素
	{if (check(row, col, board, num))
		{	board[row][col] = num + '0';
			rows[row][num] = 1; // 第row行的num已經(jīng)用過了
			cols[col][num] = 1; // 第col列的num已經(jīng)用過了
			cell[row/3][col/3][num] = 1;

			recursion(board, row, col + 1);

			if (flag) return;
			board[row][col] = '.';
			rows[row][num] = 0; // 第row行的num沒用過
			cols[col][num] = 0; // 第col列的num沒用過
			cell[row/3][col/3][num] = 0;
		}
	}

}
void solveSudoku(vector>& board)
{memset(rows, 0, sizeof(rows));
	memset(cols, 0, sizeof(cols));
	memset(cell, 0, sizeof(cell));
	for (int i = 0; i<9; i++)
		for (int j = 0; j<9; j++)
		{	if (board[i][j] != '.')
			{		int num = board[i][j] - '0';
				rows[i][num] = 1; // 第i行的num已經(jīng)用過了
				cols[j][num] = 1; // 第j列的num已經(jīng)用過了;
				cell[i/3][j/3][num] = 1;
			}
		}
	recursion(board, 0, 0);
}
};

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


當(dāng)前題目:代碼隨想錄算法訓(xùn)練營第十三天|n皇后&數(shù)獨(dú)老經(jīng)典了-創(chuàng)新互聯(lián)
轉(zhuǎn)載源于:http://weahome.cn/article/jjede.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部