int n = 3; int N = n * n; //分别代表每一行、列、方块中0-9填写的数字出现的次数 int [][] rows = newint[N][N + 1]; int [][] columns = newint[N][N + 1]; int [][] boxes = newint[N][N + 1];
publicvoidsolveSudoku(char[][] board){ this.board = board; // 初始化 for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { char num = board[i][j]; if (num != '.') { int d = Character.getNumericValue(num); placeNumber(d, i, j); } } } backtrack(0, 0); }
publicbooleancouldPlace(int d, int row, int col){ /* * 检查该位置是否能放数字 */ int idx = (row / n ) * n + col / n; return rows[row][d] + columns[col][d] + boxes[idx][d] == 0; } publicvoidplaceNumber(int d, int row, int col){ /* Place a number d in (row, col) cell */ int idx = (row / n ) * n + col / n; rows[row][d]++; columns[col][d]++; boxes[idx][d]++; board[row][col] = (char)(d + '0'); } publicvoidremoveNumber(int d, int row, int col){ /* Remove a number which didn't lead to a solution */ int idx = (row / n ) * n + col / n; rows[row][d]--; columns[col][d]--; boxes[idx][d]--; board[row][col] = '.'; } publicvoidplaceNextNumbers(int row, int col){ if ((col == N - 1) && (row == N - 1)) { sudokuSolved = true; } // if not yet else { // if we're in the end of the row // go to the next row if (col == N - 1) backtrack(row + 1, 0); // go to the next column else backtrack(row, col + 1); } }
publicvoidbacktrack(int row, int col){ /* Backtracking */ // 如果这个位置为空 if (board[row][col] == '.') { //从 0->9进行遍历 for (int d = 1; d < 10; d++) { if (couldPlace(d, row, col)) { placeNumber(d, row, col); placeNextNumbers(row, col); // if sudoku is solved, there is no need to backtrack // since the single unique solution is promised if (!sudokuSolved) removeNumber(d, row, col); } } } else placeNextNumbers(row, col); } }
publicvoidaddSolution(){ List<String> solution = new ArrayList<String>(); for (int i = 0; i < n; ++i) { int col = queens[i]; StringBuilder sb = new StringBuilder(); for(int j = 0; j < col; ++j) sb.append("."); sb.append("Q"); for(int j = 0; j < n - col - 1; ++j) sb.append("."); solution.add(sb.toString()); } output.add(solution); }
publicvoidbacktrack(int row){ for (int col = 0; col < n; col++) { if (isNotUnderAttack(row, col)) { placeQueen(row, col); // 放满了 if (row + 1 == n) addSolution(); // if not proceed to place the rest else backtrack(row + 1); // backtrack removeQueen(row, col); } } } }
/* // Definition for a Node. class Node { public int val; public Node left; public Node right; public Node next; public Node() {} public Node(int _val) { val = _val; } public Node(int _val, Node _left, Node _right, Node _next) { val = _val; left = _left; right = _right; next = _next; } }; */
/* // Definition for a Node. class Node { public int val; public Node left; public Node right; public Node next; public Node() {} public Node(int _val) { val = _val; } public Node(int _val, Node _left, Node _right, Node _next) { val = _val; left = _left; right = _right; next = _next; } }; */
classSolution{ publicintthreeSumClosest(int[] nums, int target){ Arrays.sort(nums); int p1 =0; int p2 =nums.length-1; int closetNum = nums[0]+nums[1]+nums[2]; for (int i = 0; i < nums.length; i++) { if (i > 0 && nums[i] == nums[i - 1]) continue; p1=i+1;p2 = nums.length-1; int sum = 0; //转化为两数之和 while (p1<p2) { sum = nums[p1]+nums[p2]+nums[i]; //改变closetNum if(Math.abs(sum-target)<Math.abs(closetNum-target)){ closetNum = sum; }
classSolution{ publicbooleancontainsNearbyDuplicate(int[] nums, int k){ // 用散列表来维护这个kk大小的滑动窗口。 Set<Integer> set = new HashSet<>(); for (int i = 0; i < nums.length; ++i) { if (set.contains(nums[i])) returntrue; set.add(nums[i]); if (set.size() > k) { set.remove(nums[i - k]); } } returnfalse; } }
220.存在重复元素III
在整数数组 nums 中,是否存在两个下标 i 和 j,使得 nums [i] 和 nums [j] 的差的绝对值小于等于 t ,且满足 i 和 j 的差的绝对值也小于等于 ķ 。
classSolution{ publicbooleancontainsNearbyAlmostDuplicate(int[] nums, int k, int t){ TreeSet<Integer> set = new TreeSet<>(); for (int i = 0; i < nums.length; ++i) { // 返回set中大于或者等于给定元素的最小元素,如果不存在这样的元素,返回null. Integer s = set.ceiling(nums[i]); if (s != null && s <= nums[i] + t) returntrue;
// 返回在这个集合中小于或者等于给定元素的最大元素,如果不存在这样的元素,返回null. Integer g = set.floor(nums[i]); if (g != null && nums[i] <= g + t) returntrue; //维持滑动窗口 set.add(nums[i]); if (set.size() > k) { set.remove(nums[i - k]); } } returnfalse; } }
classSolution{ publicintrob(int[] nums){ int pre = 0, cur = 0, tmp; for (int num : nums) { tmp = cur; cur = Math.max(pre + num, cur); pre = tmp; } return cur; } }
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ classSolution{
publicintrob(TreeNode root){ int[] res = dfs(root); return Math.max(res[0], res[1]); }
classSolution{ List<String> res = null; public List<String> generateParenthesis(int n){ res = new ArrayList<>(); char [] Parenthesis = newchar[2*n]; for (int i = 0; i < Parenthesis.length; i++) { Parenthesis[i]='('; } dfs(Parenthesis,1,0); return res; }
voiddfs(char[] Parenthesis,int index,int count){ if (count==Parenthesis.length/2) { res.add(String.valueOf(Parenthesis)); return; }
for (int i = index; i < Parenthesis.length; i++) { if (i+1<(count+1)*2) continue; Parenthesis[i] = ')'; dfs(Parenthesis,i+1,count+1); Parenthesis[i]='('; } } }
/** * 困难级别,以后需要回看一下 */ publicclasslongestValidParentheses{ //动态规划 publicintLongestValidParentheses(String s){ int maxans = 0; int []dp = newint[s.length()]; for (int i = 1; i < dp.length; i++) { if (s.charAt(i)==')') {
//使用栈的方法进行 publicintLongestValidParentheses2(String s){ int maxans = 0; //将下标存进去 Stack<Integer> stack = new Stack<>(); stack.push(-1); for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == '(') { stack.push(i); } else { stack.pop(); if (stack.empty()) { stack.push(i); } else { maxans = Math.max(maxans, i - stack.peek()); } } } return maxans; }
//贪心算法 publicintlongestValidParentheses3(String s){ int left = 0, right = 0, maxlength = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == '(') { left++; } else { right++; } if (left == right) { maxlength = Math.max(maxlength, 2 * right); } elseif (right > left) { left = right = 0; } } left = right = 0; for (int i = s.length() - 1; i >= 0; i--) { if (s.charAt(i) == '(') { left++; } else { right++; } if (left == right) { maxlength = Math.max(maxlength, 2 * left); } elseif (left > right) { left = right = 0; } } return maxlength; }
publicstaticvoidmain(String[] args){ longestValidParentheses l = new longestValidParentheses(); String s = "()(())"; System.out.println(l.LongestValidParentheses(s)); } }
classSolution{ public List<List<Integer>> permute(int[] nums) { public List<List<Integer>> permute(int[] nums) { List<List<Integer>> res = new ArrayList<>(); dfs(nums, res, 0); return res; }
privatevoiddfs(int[]nums,List<List<Integer>> res,int index){ if (index==nums.length-1) { List<Integer> path = new ArrayList<>(); for (int i = 0; i < nums.length; i++) { path.add(nums[i]); } res.add(path); }
for (int i = index; i < nums.length; i++) { //排列树进行交换 swap(nums, index, i); dfs(nums,res,index+1); swap(nums, index, i); } }
classSolution{ public String getPermutation(int n, int k){ StringBuilder res = new StringBuilder(); StringBuilder num = new StringBuilder("123456789"); int[] f= newint[n]; f[0] = 1; for (int i = 1; i < f.length; i++) { f[i] = f[i-1]*i; } --k; for (int i = n; i >=1; --i) { int j = k/f[i-1]; k%=f[i-1]; res.append(num.charAt(j)); num.deleteCharAt(j); } return res.toString(); } }
classSolution{ List<List<Integer>> res = new ArrayList<>(); public List<List<Integer>> subsets(int[] nums) { ArrayList<Integer>ans = new ArrayList<>(); dfs(nums,ans,0); return res; }
/** * 回溯 * @param nums * @param ans * @param n 从第n个数开始没有被访问 */ publicvoiddfs(int []nums,ArrayList<Integer>ans,int n){ res.add(new ArrayList(ans)); for (int i = n; i < nums.length; i++) { ans.add(nums[i]); dfs(nums, ans, i+1); ans.remove(ans.size()-1); } } }
classSolution{ List<List<Integer>> res = new ArrayList<>(); public List<List<Integer>> subsetsWithDup(int[] nums) { Arrays.sort(nums); List<Integer>ans = new ArrayList<>(); dfs(nums,ans,0); return res; }
publicvoiddfs(int []nums,List<Integer>ans,int n){ res.add(new ArrayList(ans)); for (int i = n; i < nums.length; i++) { //剪枝情况 //这个判断需要理解 if (i > n && nums[i] == nums[i - 1] ) continue; ans.add(nums[i]); dfs(nums, ans, i+1); ans.remove(ans.size()-1); } } }
组合
题目描述
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
示例:
1 2 3 4 5 6 7 8 9 10
输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
classSolution{ List<List<Integer>> res = new LinkedList<>(); int k; int []nums; public List<List<Integer>> combine(int n, int k) { nums = newint[n]; this.k=k; for (int i = 0; i < nums.length; i++) { nums[i] = i+1; } LinkedList<Integer> path = new LinkedList<>(); dfs(path,0); return res; } voiddfs(LinkedList<Integer> path,int n){ if (path.size()==k) { res.add(new LinkedList(path)); return ; }
for (int i = n; i < nums.length; i++) { path.add(nums[i]); dfs(path,i+1); path.removeLast(); } } }
classSolution{ List<List<Integer>> output = new LinkedList(); int n; int k;
publicvoidbacktrack(int first, LinkedList<Integer> curr){ // if the combination is done if (curr.size() == k) output.add(new LinkedList(curr));
for (int i = first; i < n + 1; ++i) { // add i into the current combination curr.add(i); // use next integers to complete the combination backtrack(i + 1, curr); // backtrack curr.removeLast(); } }
public List<List<Integer>> combine(int n, int k) { this.n = n; this.k = k; backtrack(1, new LinkedList<Integer>()); return output; } }
classSolution{ List<List<Integer>> res = null; int[] candidates; public List<List<Integer>> combinationSum(int[] candidates, int target) { res = new LinkedList<>(); if (candidates!=null&&candidates.length>0) { LinkedList<Integer> choose = new LinkedList<>(); this.candidates = candidates; dfs(choose,target,0); } return res; }
classSolution{ List<List<Integer>> res = null; int[] candidates; public List<List<Integer>> combinationSum2(int[] candidates, int target) { res = new LinkedList<>(); if (candidates!=null&&candidates.length>0) { LinkedList<Integer> choose = new LinkedList<>(); Arrays.sort(candidates); this.candidates = candidates;
for (int i = index; i < candidates.length; i++) { //大于 index 这个很灵性,需要和大于 0 进行对比 //大于 index说明index本身是可以取的 if (i>index && candidates[i]==candidates[i-1]) { continue; }
classSolution{ publicintsearch(int[] nums, int target){ if (nums==null||nums.length==0) { return -1; } int left = 0; int right = nums.length-1; int mid = 0;
//使用二分法解决 //这里是<=号,为了防止nums.length=1的情况 while (left<=right) { mid = (left+right)/2; if(nums[mid]==target)return mid; //这里也是<=号,为了处理类似于left=right=nums.length的情况 //此时mid=nums.length,如果这路不是<=,就会进入下面nums[mid+1]进行判断,可能出现越界 if (nums[left]<=nums[mid]) { //说明 从 left到mid都为有序 if (nums[left]<=target && nums[mid]>target) { //说明 target在left到mid right = mid-1; } else { //说明 target在left到mid left = mid+1; } }else{ //说明 从 mid+1到right为有序 if (nums[mid+1]<=target && nums[right]>=target) { //说明在 mid+1到right left = mid+1; } else { right = mid-1; } } } return -1; } }
classSolution{ publicbooleansearch(int[] nums, int target){ if (nums==null||nums.length==0) { returnfalse; } int left = 0; int right = nums.length-1; int mid = 0;
//使用二分法解决 while (left<=right) { mid = (left+right)/2; if(nums[mid]==target)returntrue; //多这个判断,将非选择答案去掉 if (nums[left] == nums[mid]) { left++; continue; }
if (nums[left]<nums[mid]) { //说明 从 left到mid都为有序 if (nums[left]<=target && nums[mid]>target) { //说明 target在left到mid right = mid-1; } else { //说明 target在left到mid left = mid+1; } }else{ //说明 从 mid+1到right为有序 if (nums[mid+1]<=target && nums[right]>=target) { //说明在 mid+1到right left = mid+1; } else { right = mid-1; } } } returnfalse; } }