赞
踩
给定一个不含重复数字的数组 nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
- class Solution {
- public List<List<Integer>> permute(int[] nums) {
- List<List<Integer>> list = new ArrayList<>();
- dfs(nums,new boolean[nums.length],new LinkedList<Integer>(),list);
- return list;
- }
-
- public void dfs(int[] nums , boolean[] isVisited , LinkedList<Integer> stack , List<List<Integer>> list){
- if(stack.size() == nums.length){
- list.add(new ArrayList(stack));
- return;
- }
- for(int i = 0 ; i < nums.length ; i++){
- if(!isVisited[i]){
- isVisited[i] = true;
- stack.push(nums[i]);
- dfs(nums , isVisited , stack , list);
- stack.pop();
- isVisited[i] = false;
- }
- }
- }
- }
给定一个可包含重复数字的序列 nums
,按任意顺序 返回所有不重复的全排列。
- class Solution {
- public List<List<Integer>> permuteUnique(int[] nums) {
- Arrays.sort(nums);
- List<List<Integer>> list = new ArrayList<>();
- dfs(nums,new boolean[nums.length],new LinkedList<Integer>(),list);
- return list;
- }
-
- public void dfs(int[] nums , boolean[] isVisited , LinkedList<Integer> stack , List<List<Integer>> list){
- if(stack.size() == nums.length){
- list.add(new ArrayList(stack));
- return;
- }
- for(int i = 0 ; i < nums.length ; i++){
- if (i > 0 && nums[i] == nums[i - 1] && !isVisited[i-1]) {
- continue;
- }
- if(!isVisited[i]){
- isVisited[i] = true;
- stack.push(nums[i]);
- dfs(nums , isVisited , stack , list);
- stack.pop();
- isVisited[i] = false;
- }
- }
- }
- }
给你一个整数数组 nums
,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
- class Solution {
- public List<List<Integer>> subsets(int[] nums) {
- List<List<Integer>> res = new ArrayList<>();
- res.add(new ArrayList<>());
- for(int i = 1; i <= nums.length;i++){
- res = getSub(0,new LinkedList<>(),nums,i,res);
- }
- return res;
- }
- private List<List<Integer>> getSub(int begin, LinkedList<Integer> list,int[] nums,int full,List<List<Integer>> res){
- if(list.size() == full){
- res.add(new ArrayList<>(list));
- }
- for(int i = begin; i < nums.length; i++){
- list.push(nums[i]);
- getSub(i+1,list,nums,full,res);
- list.pop();
- }
- return res;
- }
- }
给你一个整数数组 nums
,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
- class Solution {
- List<Integer> t = new ArrayList<Integer>();
- List<List<Integer>> ans = new ArrayList<List<Integer>>();
-
- public List<List<Integer>> subsetsWithDup(int[] nums) {
- Arrays.sort(nums);
- dfs(false, 0, nums);
- return ans;
- }
-
- public void dfs(boolean choosePre, int cur, int[] nums) {
- if (cur == nums.length) {
- ans.add(new ArrayList<Integer>(t));
- return;
- }
- dfs(false, cur + 1, nums);
- if (!choosePre && cur > 0 && nums[cur - 1] == nums[cur]) {
- return;
- }
- t.add(nums[cur]);
- dfs(true, cur + 1, nums);
- t.remove(t.size() - 1);
- }
- }
有效 IP 地址 正好由四个整数(每个整数位于 0
到 255
之间组成,且不能含有前导 0
),整数之间用 '.'
分隔。
"0.1.2.201"
和 "192.168.1.1"
是 有效 IP 地址,但是 "0.011.255.245"
、"192.168.1.312"
和 "192.168@1.1"
是 无效 IP 地址。给定一个只包含数字的字符串 s
,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s
中插入 '.'
来形成。你 不能 重新排序或删除 s
中的任何数字。你可以按 任何 顺序返回答案。
- class Solution {
- public List<String> restoreIpAddresses(String s) {
- List<String> res = new ArrayList<>();
- char[] zArr = s.toCharArray();
- if (zArr.length < 4) return res;
- back(zArr, new LinkedList<>(),res);
- return res;
- }
-
- private void back(char[] zArr, LinkedList<Integer> list, List<String> res) {
- if (list.size() == 4) {
- if (list.peekLast() == zArr.length - 1) {
- StringBuilder curr = new StringBuilder();
- int index = 0;
- for (int i = 0; i < 4; i++) {
- int num = list.get(i);
- while (index <= num) {
- curr.append(zArr[index++]);
- }
- if (i != 3) {
- curr.append('.');
- }
- }
- res.add(curr.toString());
- } else {
- return;
- }
- }
- if (list.isEmpty()) {
- if (zArr[0] == '0') {
- list.add(0);
- back(zArr, list, res);
- list.removeLast();
- } else {
- for (int i = 0; i < 3; i++) {
- if (inRange(zArr, 0, i)) {
- list.add(i);
- back(zArr, list, res);
- list.removeLast();
- } else {
- return;
- }
- }
- }
- } else {
- int pre = list.peekLast();
- if (pre < zArr.length - 1) {
- int curr = pre + 1;
- if (zArr[curr] == '0') {
- list.add(curr);
- back(zArr, list, res);
- list.removeLast();
- } else {
- for (int i = curr; i < zArr.length; i++) {
- if (!inRange(zArr, curr, i)) {
- return;
- } else {
- list.add(i);
- back(zArr, list, res);
- list.removeLast();
- }
- }
- }
- }
- }
- }
-
- private boolean inRange(char[] zArr, int pre, int curr) {
- int jud = 0;
- while (pre <= curr) {
- jud *= 10;
- jud += (zArr[pre] - '0');
- pre++;
- }
- return jud >= 0 && jud <= 255;
- }
- }
给你一个整数数组 nums
,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。
数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。
- class Solution {
- public List<List<Integer>> findSubsequences(int[] nums) {
- List<List<Integer>> res = new ArrayList<>();
- List<List<Integer>> container = new ArrayList<>();
- Map<List<Integer>, TreeSet<Integer>> map = new HashMap<>();
- TreeSet<Integer> set = new TreeSet<>();
- for (int num : nums) {
- int size = container.size();
- for (int i = 0; i < size; i++) {
- List<Integer> list = container.get(i);
- if (list.get(list.size() - 1) <= num) {
- TreeSet<Integer> treeSet = map.get(list);
- if (treeSet.add(num)) {
- List<Integer> addList = new ArrayList<>(list);
- addList.add(num);
- container.add(addList);
- map.put(addList, new TreeSet<>());
- }
- }
- }
- if (set.add(num)) {
- ArrayList<Integer> list = new ArrayList<>(List.of(num));
- container.add(list);
- map.put(list, new TreeSet<>());
- }
- }
- for (List<Integer> list : container) {
- if (list.size() >= 2) res.add(list);
- }
- return res;
- }
- }
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
1-9
在每一行只能出现一次。1-9
在每一列只能出现一次。1-9
在每一个以粗实线分隔的 3x3
宫内只能出现一次。(请参考示例图)数独部分空格内已填入了数字,空白格用 '.'
表示。
- class Solution {
- public void solveSudoku(char[][] board) {
- boolean[][] row = new boolean[9][9];//行
- boolean[][] column = 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 curr = (int)(board[i][j] - '1');
- row[i][curr] = true;
- column[j][curr] = true;
- block[bloNums(i,j)][curr] = true;
- }
- }
- }
- dfs(board,0,0,row,column,block);
- }
- private boolean dfs(char[][] board, int i, int j, boolean[][] row, boolean[][] column, boolean[][] block){
- if(i >= 9) return true;
- if(j >= 9){ return dfs(board,i+1,0,row,column,block);}
- if(board[i][j] != '.'){return dfs(board,i,j+1,row,column,block);}
-
- for(int curr = 0; curr < 9; curr++){
- if(!row[i][curr] && !column[j][curr] && !block[bloNums(i,j)][curr]){
- board[i][j] = (char)(curr+'1');
- row[i][curr] = true;
- column[j][curr] = true;
- block[bloNums(i,j)][curr] = true;
- if(dfs(board,i,j+1,row,column,block)){
- return true;
- }
- board[i][j] = '.';
- row[i][curr] = false;
- column[j][curr] = false;
- block[bloNums(i,j)][curr] = false;
- }
- }
- return false;
- }
- private int bloNums(int row, int column){
- return row/3*3 + column/3;
- }
- }
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n
个皇后放置在 n×n
的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n
,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
- class Solution {
- public List<List<String>> solveNQueens(int n) {
- List<List<String>> res = new ArrayList<>();
- char[][] chs = new char[n][n];
- for (char[] ch : chs) {
- Arrays.fill(ch, '.');
- }
- boolean[] column = new boolean[n];//列
- boolean[] left = new boolean[2 * n - 1];//左斜线 - / i+j
- boolean[] right = new boolean[2 * n - 1];//右斜线 - \ n-1-(i-j)
-
- dfs(chs,0,column,left,right,res);
- return res;
- }
-
- static void dfs(char[][] chs, int i, boolean[] column, boolean[] left, boolean[] right, List<List<String>> res) {
- if (i == chs.length){
- List<String> list = new ArrayList<>();
- for (char[] ch : chs) {
- list.add(new String(ch));
- }
- res.add(list);
- return;
- }
-
- for (int j = 0; j < chs.length; j++) {
- if (column[j] || left[i + j] || right[chs.length + j - i - 1]) continue;
-
-
- chs[i][j] = 'Q';
- column[j] = left[i + j] = right[chs.length + j - i - 1] = true;
- dfs(chs, i + 1, column, left, right, res);
- chs[i][j] = '.';
- column[j] = left[i + j] = right[chs.length + j - i - 1] = false;
- }
-
- }
- }
给你一份航线列表 tickets
,其中 tickets[i] = [fromi, toi]
表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。
所有这些机票都属于一个从 JFK
(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK
开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。
["JFK", "LGA"]
与 ["JFK", "LGB"]
相比就更小,排序更靠前。假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。
- class Solution {
- boolean over = false;
- List<String> res = new ArrayList<>();
-
- public List<String> findItinerary(List<List<String>> tickets) {
- Map<String, TreeMap<String, Integer>> map = new HashMap<>();
- int sum = tickets.size();
-
- for (List<String> ticket : tickets) {
- String from = ticket.get(0);
- String to = ticket.get(1);
- if (map.get(from) == null) {
- TreeMap<String, Integer> treeMap = new TreeMap<>();
- treeMap.put(to, 1);
- map.put(from, treeMap);
- } else {
- TreeMap<String, Integer> treeMap = map.get(from);
- treeMap.merge(to, 1, Integer::sum);
- }
- }
- res.add("JFK");
- dfs("JFK",sum,map);
- return res;
- }
-
- private void dfs(String from, int sum, Map<String, TreeMap<String, Integer>> map) {
- if (sum == 0) {
- over = true;
- return;
- }
- TreeMap<String, Integer> treeMap = map.get(from);
- if(treeMap == null || treeMap.isEmpty()) return;
- for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
- String key = entry.getKey();
- Integer value = entry.getValue();
- if (value > 0) {
- value--;
- treeMap.put(key,value);
- res.add(key);
- dfs(key, sum - 1, map);
- if(over){
- return;
- }
- res.remove(res.size() - 1);
- value++;
- treeMap.put(key,value);
- }
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。