1.组合
77. 组合 - 力扣(LeetCode)
方法一:递归实现组合型枚举
class Solution {List<Integer> temp = new ArrayList<Integer>();List<List<Integer>> ans = new ArrayList<List<Integer>>();public List<List<Integer>> combine(int n, int k) {dfs(1, n, k);return ans;}public void dfs(int cur, int n, int k) {// 剪枝:temp 长度加上区间 [cur, n] 的长度小于 k,不可能构造出长度为 k 的 tempif (temp.size() + (n - cur + 1) < k) {return;}// 记录合法的答案if (temp.size() == k) {ans.add(new ArrayList<Integer>(temp));return;}// 考虑选择当前位置temp.add(cur);dfs(cur + 1, n, k);temp.remove(temp.size() - 1);// 考虑不选择当前位置dfs(cur + 1, n, k);}
}
2.子集
给你一个整数数组
nums
,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
78. 子集 - 力扣(LeetCode)
方法一:迭代法实现子集枚举
class Solution {List<Integer> t = new ArrayList<Integer>();List<List<Integer>> ans = new ArrayList<List<Integer>>();public List<List<Integer>> subsets(int[] nums) {int n = nums.length;for (int mask = 0; mask < (1 << n); ++mask) {t.clear();for (int i = 0; i < n; ++i) {if ((mask & (1 << i)) != 0) {t.add(nums[i]);}}ans.add(new ArrayList<Integer>(t));}return ans;}
}
方法二:递归法实现子集枚举
class Solution {List<Integer> t = new ArrayList<Integer>();List<List<Integer>> ans = new ArrayList<List<Integer>>();public List<List<Integer>> subsets(int[] nums) {dfs(0, nums);return ans;}public void dfs(int cur, int[] nums) {if (cur == nums.length) {ans.add(new ArrayList<Integer>(t));return;}t.add(nums[cur]);dfs(cur + 1, nums);t.remove(t.size() - 1);dfs(cur + 1, nums);}
}
3.单词搜索
给定一个 m x n
二维字符网格 board
和一个字符串单词 word
。如果 word
存在于网格中,返回 true
;否则,返回 false
。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
79. 单词搜索 - 力扣(LeetCode)
方法一:回溯
class Solution {public boolean exist(char[][] board, String word) {int h = board.length, w = board[0].length;boolean[][] visited = new boolean[h][w];for (int i = 0; i < h; i++) {for (int j = 0; j < w; j++) {boolean flag = check(board, visited, i, j, word, 0);if (flag) {return true;}}}return false;}public boolean check(char[][] board, boolean[][] visited, int i, int j, String s, int k) {if (board[i][j] != s.charAt(k)) {return false;} else if (k == s.length() - 1) {return true;}visited[i][j] = true;int[][] directions = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};boolean result = false;for (int[] dir : directions) {int newi = i + dir[0], newj = j + dir[1];if (newi >= 0 && newi < board.length && newj >= 0 && newj < board[0].length) {if (!visited[newi][newj]) {boolean flag = check(board, visited, newi, newj, s, k + 1);if (flag) {result = true;break;}}}}visited[i][j] = false;return result;}
}
4.删除有序数组的重复项
给你一个有序数组
nums
,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
方法一:双指针(快慢指针)
class Solution {public int removeDuplicates(int[] nums) {int n=nums.length;if(n<=2){return n;}int slow=2,fast=2;while(fast<n){if(nums[slow-2]!=nums[fast]){nums[slow]=nums[fast];slow++;}fast++;}return slow;}
}
5.搜索旋转排序数组 II
81. 搜索旋转排序数组 II - 力扣(LeetCode)
方法一:二分查找
class Solution {public boolean search(int[] nums, int target) {int n = nums.length;if (n == 0) {return false;}if (n == 1) {return nums[0] == target;}int l = 0, r = n - 1;while (l <= r) {int mid = (l + r) / 2;if (nums[mid] == target) {return true;}if (nums[l] == nums[mid] && nums[mid] == nums[r]) {++l;--r;} else if (nums[l] <= nums[mid]) {if (nums[l] <= target && target < nums[mid]) {r = mid - 1;} else {l = mid + 1;}} else {if (nums[mid] < target && target <= nums[n - 1]) {l = mid + 1;} else {r = mid - 1;}}}return false;}
}