1. 程式人生 > 其它 >leetcode 46 全排列, leetocde 47, leetcode 51 N皇后

leetcode 46 全排列, leetocde 47, leetcode 51 N皇后

技術標籤:leetcodeleetcode

46. 全排列(中等)

給定一個 沒有重複 數字的序列,返回其所有可能的全排列。

示例:

輸入: [1,2,3]
輸出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]


用vis標記是否訪問過的狀態。

class Solution {
public:    
    vector<vector<int>> results;
    vector<int> result;
    vector<int> vis;
    vector
<vector<int>> permute(vector<int>& nums) { vis.resize(nums.size()); sort(nums.begin(), nums.end()); dfs(nums, 0); return results; } void dfs(vector<int>& nums, int id) { if(id == nums.size()) { results.push_back(result); return
; } for(int i = 0; i < nums.size(); i++) { if(vis[i]) continue; result.push_back(nums[i]); vis[i] = 1; dfs(nums, id + 1); vis[i] = 0; result.pop_back(); } } };
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

47. 全排列 II(中等)

給定一個可包含重複數字的序列 nums ,按任意順序 返回所有不重複的全排列。

示例 1:

輸入:nums = [1,1,2]
輸出:
[[1,1,2],
[1,2,1],
[2,1,1]]


與上題類似。先sort,然後if((i > 0 && nums[i] == nums[i - 1] && vis[i-1]) || vis[i]) continue;去重即可

class Solution {
public:    
    vector<vector<int>> results;
    vector<int> result;
    vector<int> vis;
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vis.resize(nums.size());
        sort(nums.begin(), nums.end());
        dfs(nums, 0);
        return results;
    }
    void dfs(vector<int>& nums, int id)
    {
        if(id == nums.size())
        {
            results.push_back(result);
            return;
        }
        for(int i = 0; i < nums.size(); i++)
        {
            if((i > 0 && nums[i] == nums[i - 1] && vis[i-1]) || vis[i])
                continue;
            result.push_back(nums[i]);
            vis[i] = 1;
            dfs(nums, id + 1);
            vis[i] = 0;            
            result.pop_back();
        }
    }
};
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

51. N 皇后困難

轉自labuladong 回溯。

vector<vector<string>> res;

/* 輸入棋盤邊長 n,返回所有合法的放置 */
vector<vector<string>> solveNQueens(int n) {
    // '.' 表示空,'Q' 表示皇后,初始化空棋盤。
    vector<string> board(n, string(n, '.'));
    backtrack(board, 0);
    return res;
}

// 路徑:board 中小於 row 的那些行都已經成功放置了皇后
// 選擇列表:第 row 行的所有列都是放置皇后的選擇
// 結束條件:row 超過 board 的最後一行
void backtrack(vector<string>& board, int row) {
    // 觸發結束條件
    if (row == board.size()) {
        res.push_back(board);
        return;
    }
    
    int n = board[row].size();
    for (int col = 0; col < n; col++) {
        // 排除不合法選擇
        if (!isValid(board, row, col)) 
            continue;
        // 做選擇
        board[row][col] = 'Q';
        // 進入下一行決策
        backtrack(board, row + 1);
        // 撤銷選擇
        board[row][col] = '.';
    }
}
/* 是否可以在 board[row][col] 放置皇后? */
bool isValid(vector<string>& board, int row, int col) {
    int n = board.size();
    // 檢查列是否有皇后互相沖突
    for (int i = 0; i < n; i++) {
        if (board[i][col] == 'Q')
            return false;
    }
    // 檢查右上方是否有皇后互相沖突
    for (int i = row - 1, j = col + 1; 
            i >= 0 && j < n; i--, j++) {
        if (board[i][j] == 'Q')
            return false;
    }
    // 檢查左上方是否有皇后互相沖突
    for (int i = row - 1, j = col - 1;
            i >= 0 && j >= 0; i--, j--) {
        if (board[i][j] == 'Q')
            return false;
    }
    return true;
}