leetcode(36-40)

36. 有效的数独

判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

上图是一个部分填充的有效的数独。

数独部分空格内已填入了数字,空白格用 '.' 表示。

示例 1:

输入:
[
  ["5","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
输出: true

示例 2:

输入:
[
  ["8","3",".",".","7",".",".",".","."],
  ["6",".",".","1","9","5",".",".","."],
  [".","9","8",".",".",".",".","6","."],
  ["8",".",".",".","6",".",".",".","3"],
  ["4",".",".","8",".","3",".",".","1"],
  ["7",".",".",".","2",".",".",".","6"],
  [".","6",".",".",".",".","2","8","."],
  [".",".",".","4","1","9",".",".","5"],
  [".",".",".",".","8",".",".","7","9"]
]
输出: false
解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。
     但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

说明:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。
  • 给定数独序列只包含数字 1-9 和字符 '.' 。
  • 给定数独永远是 9x9 形式的。
class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        for(int i=0;i<9;i++){
            int row[9]={0};
            int col[9]={0};
            int cube[9]={0};
            for(int j=0;j<9;j++){
                if(board[i][j]!='.'){
                    if(row[board[i][j]-'1']==1) return false;
                    else row[board[i][j]-'1']=1;
                }
                if(board[j][i]!='.'){
                    if(col[board[j][i]-'1']==1) return false;
                    else col[board[j][i]-'1']=1;
                }
                int cubeX=3*(i/3)+j/3;
                int cubeY=3*(i%3)+j%3;
                if(board[cubeX][cubeY]!='.'){
                    if(cube[board[cubeX][cubeY]-'1']==1) return false;
                    else cube[board[cubeX][cubeY]-'1']=1;
                }
            }
        }
        return true;
    }
};

37. 解数独

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则

扫描二维码关注公众号,回复: 3710722 查看本文章
  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

空白格用 '.' 表示。

一个数独。

答案被标成红色。

Note:

  • 给定的数独序列只包含数字 1-9 和字符 '.' 。
  • 你可以假设给定的数独只有唯一解。
  • 给定数独永远是 9x9 形式的。
class Solution {
public:
    int row[9][10];
    int column[9][10];
    int grid[9][10];
    int flag=0;
    void solve(int r,int c,vector<vector<char>>& board)
    {
        int i;
        if(r==9) {
            flag=1;
            return;
        }
        if(board[r][c]=='.') {
            for(i=1;i<=9;i++) {
                if(row[r][i]==0&&column[c][i]==0&&grid[3*(r/3)+c/3][i]==0){
                    board[r][c]=i+'0';
                    row[r][i]=1;
                    column[c][i]=1;
                    grid[3*(r/3)+c/3][i]=1;
                    if(c==8) solve(r+1,0,board);
                    else solve(r,c+1,board);
                    if(flag==1) return;
                    board[r][c]='.';
                    row[r][i]=0;
                    column[c][i]=0;
                    grid[3*(r/3)+c/3][i]=0; 
                }
            }
        }
        else{
            if(c==8) solve(r+1,0,board);
            else solve(r,c+1,board);
        }
    }
    void solveSudoku(vector<vector<char>>& board) {
        int i,j,k;
        for(i=0;i<9;i++){
            for(j=0;j<10;j++)
                row[i][j]=column[i][j]=grid[i][j]=0;
        }
        for(i=0;i<9;i++){
            for(j=0;j<9;j++){
                if(board[i][j]!='.'){
                    k=board[i][j]-'0';
                    row[i][k]=1;
                    column[j][k]=1;
                    grid[(i/3)*3+j/3][k]=1;
                }
            }
        }
        solve(0,0,board);
    }
};

38. 报数

数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:

1.     1
2.     11
3.     21
4.     1211
5.     111221

1 被读作  "one 1"  ("一个一") , 即 11
11 被读作 "two 1s" ("两个一"), 即 21
21 被读作 "one 2",  "one 1" ("一个二" ,  "一个一") , 即 1211

给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。

注意:整数顺序将表示为一个字符串。

示例 1:

输入: 1
输出: "1"

示例 2:

输入: 4
输出: "1211"
class Solution {
public:
    string countAndSay(int n) {
        string res="1",temp="";
        for(int i=1;i<n;i++)
        {
            int t=0;
            while(t<res.length())
            {
                int num=1;
                while(res[t]==res[t+1]&&(t+1)<res.length())
                {
                    num++;
                    t++;
                }
                temp=temp+to_string(num)+res[t];
                t++;
            }
            res=temp;
            temp="";
        }
        return res;
    }
};

39. 组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

  • 所有数字(包括 target)都是正整数。
  • 解集不能包含重复的组合。 

示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
  [7],
  [2,2,3]
]

示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]
class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        vector<vector<int>> res;
        vector<int> tmp;
        findAll(candidates, res,tmp,target,0);
        return res;
    }
    void findAll(const vector<int>& candidates, vector<vector<int>>& res, vector<int>& tmp, int target, int index)
    {
        if (target == 0) {
            res.push_back(tmp);
            return;
        } 
        if (target < candidates[0]){
            return;
        }
        for(int i = index; i < candidates.size(); ++i){
            tmp.push_back(candidates[i]);
            findAll(candidates, res, tmp, target-candidates[i],i);
            temp.pop_back(); 
            }
        }
};

40. 组合总和 II

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

  • 所有数字(包括目标数)都是正整数。
  • 解集不能包含重复的组合。 

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
  [1,2,2],
  [5]
]
class Solution {
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        vector<vector<int>> res;
        vector<int> tmp;
        find(candidates,tmp,res,target,0);
        return res;
    }
    void find(vector<int>& candidates,vector<int>& tmp,vector<vector<int>>& res,int target,int index){
        for(int i=index;i<candidates.size();i++){
            if(target==candidates[i]){
                tmp.push_back(candidates[i]);
                res.push_back(tmp);
                tmp.pop_back();
                return;
            }
            if(target<candidates[i]){
                return;
            } else {
                tmp.push_back(candidates[i]);
                find(candidates,tmp,res,target-candidates[i],i+1);
                tmp.pop_back();
                while(i<candidates.size()-1 && candidates[i]==candidates[i+1]){
                    i++;
                }
            }
        }
    }
};

(以上题目均摘自leetcode)

猜你喜欢

转载自blog.csdn.net/github_37002236/article/details/83001768