1. 全排列 II
给定一个可包含重复数字的序列 nums
,按任意顺序 返回所有不重复的全排列。
示例 1:
输入:nums = [1,1,2]
输出:[[1,1,2], [1,2,1], [2,1,1]]
示例 2:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
提示:
1 <= nums.length <= 8
-10 <= nums[i] <= 10
出处:
https://edu.csdn.net/practice/27137143
代码1:
class Solution { List<List<Integer>> ans = new ArrayList<>(); public List<List<Integer>> permuteUnique(int[] nums) { dfs(nums, 0); return ans; } private void dfs(int[] nums, int cur) { if (cur == nums.length) { List<Integer> line = new ArrayList<>(); for (int i : nums) { line.add(i); } ans.add(line); } else { for (int i = cur; i < nums.length; i++) { if (canSwap(nums, cur, i)) { swap(nums, cur, i); dfs(nums, cur + 1); swap(nums, cur, i); } } } } private boolean canSwap(int nums[], int begin, int end) { for (int i = begin; i < end; i++) { if (nums[i] == nums[end]) { return false; } } return true; } private void swap(int nums[], int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } }
代码2:
import java.util.*; class permuteUnique { public static class Solution { public List<List<Integer>> permuteUnique(int[] nums) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(nums); while (true) { res.add(getList(nums)); if (!nextPermutation(nums)) { break; } } return res; } private List<Integer> getList(int[] nums) { List<Integer> list = new ArrayList<>(); for (int num : nums) { list.add(num); } return list; } private boolean nextPermutation(int[] nums) { int i = nums.length - 2; while (i >= 0 && nums[i] >= nums[i + 1]) { i--; } if (i < 0) { return false; } int j = nums.length - 1; while (j > i && nums[j] <= nums[i]) { j--; } swap(nums, i, j); reverse(nums, i + 1); return true; } private void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } private void reverse(int[] nums, int start) { int i = start, j = nums.length - 1; while (i < j) { swap(nums, i, j); i++; j--; } } } public static void main(String[] args) { Solution s = new Solution(); int[] nums = {1,1,2}; System.out.println(s.permuteUnique(nums)); int[] nums2 = {1,2,3}; System.out.println(s.permuteUnique(nums2)); } }
输出:
[[1, 1, 2], [1, 2, 1], [2, 1, 1]]
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
2. 岛屿数量
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]
输出:1
示例 2:
输入:grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
输出:3
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j] 的值为 '0' 或 '1'
出处:
https://edu.csdn.net/practice/27137144
代码1: dfs
import java.util.*; class numIslands { public static class Solution { public int numIslands(char[][] grid) { int islandNum = 0; for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { if (grid[i][j] == '1') { infect(grid, i, j); islandNum++; } } } return islandNum; } public void infect(char[][] grid, int i, int j) { if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] != '1') { return; } grid[i][j] = '2'; infect(grid, i + 1, j); infect(grid, i - 1, j); infect(grid, i, j + 1); infect(grid, i, j - 1); } } public static void main(String[] args) { Solution s = new Solution(); char[][] grid = { {'1','1','1','1','0'}, {'1','1','0','1','0'}, {'1','1','0','0','0'}, {'0','0','0','0','0'}}; System.out.println(s.numIslands(grid)); char[][] grid2 = { {'1','1','0','0','0'}, {'1','1','0','0','0'}, {'0','0','1','0','0'}, {'0','0','0','1','1'}}; System.out.println(s.numIslands(grid2)); } }
代码2: bfs
import java.util.*; class numIslands { public static class Solution { public int numIslands(char[][] grid) { if (grid == null || grid.length == 0) { return 0; } int m = grid.length; int n = grid[0].length; int islandNum = 0; int[] dx = {0, 0, -1, 1}; int[] dy = {-1, 1, 0, 0}; Queue<int[]> queue = new LinkedList<>(); boolean[][] visited = new boolean[m][n]; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == '1' && !visited[i][j]) { islandNum++; visited[i][j] = true; queue.offer(new int[]{i, j}); while (!queue.isEmpty()) { int[] curr = queue.poll(); for (int k = 0; k < 4; k++) { int x = curr[0] + dx[k]; int y = curr[1] + dy[k]; if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == '1' && !visited[x][y]) { visited[x][y] = true; queue.offer(new int[]{x, y}); } } } } } } return islandNum; } } public static void main(String[] args) { Solution s = new Solution(); char[][] grid = { {'1','1','1','1','0'}, {'1','1','0','1','0'}, {'1','1','0','0','0'}, {'0','0','0','0','0'}}; System.out.println(s.numIslands(grid)); char[][] grid2 = { {'1','1','0','0','0'}, {'1','1','0','0','0'}, {'0','0','1','0','0'}, {'0','0','0','1','1'}}; System.out.println(s.numIslands(grid2)); } }
输出:
1
3
3. 有效的数独
请你判断一个 9x9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.' 表示。
注意:
一个有效的数独(部分已被填充)不一定是可解的。
只需要根据以上规则,验证已经填入的数字是否有效即可。
示例 1:
输入:board =
[["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:
输入:board =
[["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 存在, 因此这个数独是无效的。
提示:
board.length == 9
board[i].length == 9
board[i][j] 是一位数字或者 '.'
出处:
https://edu.csdn.net/practice/27137145
代码1:
import java.util.*; class isValidSudoku { public static class Solution { public boolean isValidSudoku(char[][] board) { boolean[][] row = new boolean[9][9]; boolean[][] col = new boolean[9][9]; boolean[][] block = new boolean[9][9]; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (board[i][j] != '.') { int num = board[i][j] - '1'; int blockIndex = i / 3 * 3 + j / 3; if (row[i][num] || col[j][num] || block[blockIndex][num]) { return false; } else { row[i][num] = true; col[j][num] = true; block[blockIndex][num] = true; } } } } return true; } } public static void main(String[] args) { Solution s = new Solution(); char[][] board = { {'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'}}; System.out.println(s.isValidSudoku(board)); char[][] board2 = { {'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'}}; System.out.println(s.isValidSudoku(board2)); } }
代码2:
import java.util.*; class isValidSudoku { public static class Solution { public boolean isValidSudoku(char[][] board) { Map<Integer, Set<Character>> rows = new HashMap<>(); Map<Integer, Set<Character>> cols = new HashMap<>(); Map<Integer, Set<Character>> boxes = new HashMap<>(); for (int i = 0; i < 9; i++) { rows.put(i, new HashSet<>()); cols.put(i, new HashSet<>()); boxes.put(i, new HashSet<>()); } for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { char num = board[i][j]; if (num == '.') { continue; } if (rows.get(i).contains(num) || cols.get(j).contains(num) || boxes.get((i / 3) * 3 + j / 3).contains(num)) { return false; } rows.get(i).add(num); cols.get(j).add(num); boxes.get((i / 3) * 3 + j / 3).add(num); } } return true; } } public static void main(String[] args) { Solution s = new Solution(); char[][] board = { {'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'}}; System.out.println(s.isValidSudoku(board)); char[][] board2 = { {'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'}}; System.out.println(s.isValidSudoku(board2)); } }
输出:
true
false