LeetCode DAY26(332. Reconstruct Itinerary&51. N-Queens&37. Sudoku Solver)

文章介绍了使用回溯算法解决LeetCode上的三个问题:重构行程路线、N皇后问题和数独求解。在重构行程路线中,从给定的机票出发,构建最小字典序的行程。N-Queens问题中,通过回溯寻找所有不冲突的皇后布局。数独求解利用回溯法填充空格,确保每一行、每一列和每个3x3宫格的数字唯一。
摘要由CSDN通过智能技术生成

Preface

This is a new day to continue my backtracking algorithm journey.
Learn something new and keep reviewing what I learnt before.

1. Reconstruct Itinerary

LeetCode Link: 332. Reconstruct Itinerary
You are given a list of airline tickets where tickets[i] = [fromi, toi] represent the departure and the arrival airports of one flight. Reconstruct the itinerary in order and return it.

All of the tickets belong to a man who departs from “JFK”, thus, the itinerary must begin with “JFK”. If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string.

For example, the itinerary [“JFK”, “LGA”] has a smaller lexical order than [“JFK”, “LGB”].
You may assume all tickets form at least one valid itinerary. You must use all the tickets once and only once.

Analysis and Solution

BackTrack

LeetCode C++ as followings BackTrack

class Solution {
private:
// unordered_map<departure airport, map<arrival airport, number of flights>> targets
unordered_map<string, map<string, int>> targets;
bool backtracking(int ticketNum, vector<string>& result) {
    if (result.size() == ticketNum + 1) {//terminate condition
        return true;
    }
    for (pair<const string, int>& target : targets[result[result.size() - 1]]) {
        if (target.second > 0 ) { // Record whether the arrival airport has been flown
            result.push_back(target.first);
            target.second--;
            if (backtracking(ticketNum, result)) return true;
            result.pop_back();
            target.second++;
        }
    }
    return false;
}
public:
    vector<string> findItinerary(vector<vector<string>>& tickets) {
        targets.clear();
        vector<string> result;
        for (const vector<string>& vec : tickets) {
            targets[vec[0]][vec[1]]++; // Record mapping relationship
        }
        result.push_back("JFK"); // origin airport
        backtracking(tickets.size(), result);
        return result;
    }
};

2. N-Queens

LeetCode Link: 51. N-Queens
The n-queens puzzle is the problem of placing n queens on an n x n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle. You may return the answer in any order.

Each solution contains a distinct board configuration of the n-queens’ placement, where ‘Q’ and ‘.’ both indicate a queen and an empty space, respectively.

Analysis and Solution

BackTrack

LeetCode C++ as followings BackTrack

class Solution {
private:
vector<vector<string>> result;
// n is the size of chessboard that input from outside
// row is recursive to the nth line of the chessboard
void backtracking(int n, int row, vector<string>& chessboard) {
    if (row == n) {//terminate condition 
        result.push_back(chessboard);
        return;
    }
    for (int col = 0; col < n; col++) {
        if (isValid(row, col, chessboard, n)) { // put queen if it is valid
            chessboard[row][col] = 'Q'; // place queen
            backtracking(n, row + 1, chessboard);
            chessboard[row][col] = '.'; // backtrack,undo queen 
        }
    }
}
bool isValid(int row, int col, vector<string>& chessboard, int n) {
    // check column
    for (int i = 0; i < row; i++) { 
        if (chessboard[i][col] == 'Q') {
            return false;
        }
    }
    // Check if there is a queen at a 45 degree angle
    for (int i = row - 1, j = col - 1; i >=0 && j >= 0; i--, j--) {
        if (chessboard[i][j] == 'Q') {
            return false;
        }
    }
    // Check if there is a queen at a 135 degree angle
    for(int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
        if (chessboard[i][j] == 'Q') {
            return false;
        }
    }
    return true;
}
public:
    vector<vector<string>> solveNQueens(int n) {
        result.clear();
        std::vector<std::string> chessboard(n, std::string(n, '.'));
        backtracking(n, 0, chessboard);
        return result;
    }
};

3. Sudoku Solver

LeetCode Link: 37. Sudoku Solver
Write a program to solve a Sudoku puzzle by filling the empty cells.

A sudoku solution must satisfy all of the following rules:

Each of the digits 1-9 must occur exactly once in each row.
Each of the digits 1-9 must occur exactly once in each column.
Each of the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.
The ‘.’ character indicates empty cells.

Analysis and Solution

BackTrack

LeetCode C++ as followings BackTrack

class Solution {
private:
bool backtracking(vector<vector<char>>& board) {
    for (int i = 0; i < board.size(); i++) {        // iterate over rows
        for (int j = 0; j < board[0].size(); j++) { // iterate over columns
            if (board[i][j] == '.') {
                for (char k = '1'; k <= '9'; k++) {     // (i, j) judge if it is appropriate to put k in this position
                    if (isValid(i, j, k, board)) {
                        board[i][j] = k;                // place k
                        if (backtracking(board)) return true; // Return immediately if a suitable set is found
                        board[i][j] = '.';              // backtrack,undo k
                    }
                }
                return false;  // After all 9 numbers have been tried, if none work, then return false
            }                
        }
    }
    return true; // False is not returned after traversing, indicating that a suitable chessboard position has been found
}
bool isValid(int row, int col, char val, vector<vector<char>>& board) {
    for (int i = 0; i < 9; i++) { // Determine whether the row is repeated
        if (board[row][i] == val) {
            return false;
        }
    }
    for (int j = 0; j < 9; j++) { // Determine whether the column is repeated
        if (board[j][col] == val) {
            return false;
        }
    }
    int startRow = (row / 3) * 3;
    int startCol = (col / 3) * 3;
    for (int i = startRow; i < startRow + 3; i++) { // Determine whether 9 squares are repeated
        for (int j = startCol; j < startCol + 3; j++) {
            if (board[i][j] == val ) {
                return false;
            }
        }
    }
    return true;
}
public:
    void solveSudoku(vector<vector<char>>& board) {
        backtracking(board);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值