classSolution {
publicintminSubArrayLen(int target, int[] nums) {
intleft=0, sum = 0, result = Integer.MAX_VALUE;
for (intright=0; right < nums.length; right++) {
sum += nums[right];
while (sum >= target) {
result = Math.min(result, right - left + 1);
sum -= nums[left++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}
904. 水果成篮
classSolution {
publicinttotalFruit(int[] fruits) {
Map<Integer, Integer> mp = newHashMap<>();
intn= fruits.length, left = 0, ans = 0;
for (intright=0; right < n; right++) {
mp.put(fruits[right], mp.getOrDefault(fruits[right], 0) + 1);
while (mp.size() > 2) {
mp.put(fruits[left], mp.get(fruits[left]) - 1);
if (mp.get(fruits[left]) == 0) mp.remove(fruits[left]);
left++;
}
ans = Math.max(ans, right - left + 1);
}
return ans;
}
}
59. 螺旋矩阵 II
classSolution {
publicint[][] generateMatrix(int n) {
int[][] ans = newint[n][n];
intstartx=0, starty = 0, offset = 1, count = 1, loop = 1;
intx=0, y = 0;
while (loop <= n / 2) {
for (y = starty; y < n - offset; y++) ans[startx][y] = count++;
for (x = startx; x < n - offset; x++) ans[x][y] = count++;
for (; y > starty; y--) ans[x][y] = count++;
for (; x > startx; x--) ans[x][y] = count++;
loop++; offset++; startx++; starty++;
}
if (n % 2 == 1) ans[startx][starty] = count;
return ans;
}
}
54. 螺旋矩阵
classSolution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> ans = newArrayList<>();
inthang= matrix.length, lie = matrix[0].length;
intleft=0, right = lie - 1, top = 0, bottom = hang - 1;
while (left <= right && top <= bottom) {
for (inti= left; i <= right; i++) ans.add(matrix[top][i]); top++;
for (inti= top; i <= bottom; i++) ans.add(matrix[i][right]); right--;
if (top <= bottom) for (inti= right; i >= left; i--) ans.add(matrix[bottom][i]); bottom--;
if (left <= right) for (inti= bottom; i >= top; i--) ans.add(matrix[i][left]); left++;
}
return ans;
}
}
classSolution {
public ListNode detectCycle(ListNode head) {
ListNodefast= head, slow = head;
while (fast != null && fast.next != null) {
slow = slow.next; fast = fast.next.next;
if (slow == fast) {
ListNodejoint= slow, begin = head;
while (joint != begin) { joint = joint.next; begin = begin.next; }
return joint;
}
}
returnnull;
}
}
哈希表
242. 有效的字母异位词
classSolution {
publicbooleanisAnagram(String s, String t) {
int[] rec = newint[26];
for (char ch : s.toCharArray()) rec[ch - 'a']++;
for (char ch : t.toCharArray()) rec[ch - 'a']--;
for (int i : rec) if (i != 0) returnfalse;
returntrue;
}
}
383. 赎金信
classSolution {
publicbooleancanConstruct(String ransomNote, String magazine) {
int[] record = newint[26];
for (char c : magazine.toCharArray()) record[c - 'a']++;
for (char c : ransomNote.toCharArray()) record[c - 'a']--;
for (int i : record) if (i < 0) returnfalse;
returntrue;
}
}
49. 字母异位词分组
classSolution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = newHashMap<>();
for (String str : strs) {
int[] rec = newint[26];
for (char c : str.toCharArray()) rec[c - 'a']++;
StringBuilderkey=newStringBuilder();
for (inti=0; i < 26; i++) if (rec[i] != 0) { key.append((char)(i + 'a')).append(rec[i]); }
Stringk= key.toString();
map.computeIfAbsent(k, x -> newArrayList<>()).add(str);
}
returnnewArrayList<>(map.values());
}
}
438. 找到字符串中所有字母异位词
classSolution {
public List<Integer> findAnagrams(String s, String p) {
intslen= s.length(), plen = p.length();
List<Integer> ans = newArrayList<>();
if (slen < plen) return ans;
int[] scount = newint[26], pcount = newint[26];
for (inti=0; i < plen; i++) { scount[s.charAt(i) - 'a']++; pcount[p.charAt(i) - 'a']++; }
if (Arrays.equals(scount, pcount)) ans.add(0);
for (inti=0; i < slen - plen; i++) {
scount[s.charAt(i) - 'a']--;
scount[s.charAt(i + plen) - 'a']++;
if (Arrays.equals(scount, pcount)) ans.add(i + 1);
}
return ans;
}
}
349. 两个数组的交集
classSolution {
publicint[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set1 = newHashSet<>();
Set<Integer> ans = newHashSet<>();
for (int i : nums1) set1.add(i);
for (int i : nums2) if (set1.contains(i)) ans.add(i);
return ans.stream().mapToInt(Integer::intValue).toArray();
}
}
350. 两个数组的交集 II
classSolution {
publicint[] intersect(int[] nums1, int[] nums2) {
if (nums1.length > nums2.length) return intersect(nums2, nums1);
Map<Integer, Integer> map = newHashMap<>();
for (int i : nums1) map.put(i, map.getOrDefault(i, 0) + 1);
List<Integer> ans = newArrayList<>();
for (int i : nums2) {
intcount= map.getOrDefault(i, 0);
if (count > 0) { ans.add(i); count--; if (count > 0) map.put(i, count); else map.remove(i); }
}
return ans.stream().mapToInt(Integer::intValue).toArray();
}
}
202. 快乐数
classSolution {
publicbooleanisHappy(int n) {
Set<Integer> set = newHashSet<>();
while (n != 1 && !set.contains(n)) { set.add(n); n = getNext(n); }
return n == 1;
}
privateintgetNext(int n) {
intans=0;
while (n > 0) { ans += (n % 10) * (n % 10); n /= 10; }
return ans;
}
}
1. 两数之和
classSolution {
publicint[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = newHashMap<>();
for (inti=0; i < nums.length; i++) {
inttemp= target - nums[i];
if (map.containsKey(temp)) returnnewint[]{map.get(temp), i};
map.put(nums[i], i);
}
returnnewint[0];
}
}
454. 四数相加 II
classSolution {
publicintfourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer, Integer> map = newHashMap<>();
for (int i : nums1) for (int j : nums2) map.put(i + j, map.getOrDefault(i + j, 0) + 1);
intres=0;
for (int i : nums3) for (int j : nums4) res += map.getOrDefault(0 - i - j, 0);
return res;
}
}
15. 三数之和
classSolution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = newArrayList<>();
Arrays.sort(nums);
for (inti=0; i < nums.length; i++) {
if (nums[i] > 0) break;
if (i > 0 && nums[i] == nums[i - 1]) continue;
intleft= i + 1, right = nums.length - 1;
while (left < right) {
intsum= nums[i] + nums[left] + nums[right];
if (sum > 0) right--;
elseif (sum < 0) left++;
else {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++; right--;
}
}
}
return result;
}
}
18. 四数之和
classSolution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = newArrayList<>();
Arrays.sort(nums);
for (inta=0; a < nums.length; a++) {
if (nums[a] > target && nums[a] >= 0) break;
if (a > 0 && nums[a] == nums[a - 1]) continue;
for (intb= a + 1; b < nums.length; b++) {
if (nums[a] + nums[b] > target && nums[a] + nums[b] >= 0) break;
if (b > a + 1 && nums[b] == nums[b - 1]) continue;
intleft= b + 1, right = nums.length - 1;
while (right > left) {
longsum= (long) nums[a] + nums[b] + nums[left] + nums[right];
if (sum > target) right--;
elseif (sum < target) left++;
else {
res.add(Arrays.asList(nums[a], nums[b], nums[left], nums[right]));
while (left < right && nums[right] == nums[right - 1]) right--;
while (left < right && nums[left] == nums[left + 1]) left++;
right--; left++;
}
}
}
}
return res;
}
}
classSolution {
public String removeDuplicates(String s) {
Deque<Character> deque = newArrayDeque<>();
for (char c : s.toCharArray()) {
if (!deque.isEmpty() && deque.peek() == c) deque.pop();
else deque.push(c);
}
Stringstr="";
while (!deque.isEmpty()) str = deque.pop() + str;
return str;
}
}
150. 逆波兰表达式求值
classSolution {
publicintevalRPN(String[] tokens) {
Deque<Integer> deque = newArrayDeque<>();
for (String s : tokens) {
if (s.equals("+")) { inta= deque.pop(), b = deque.pop(); deque.push(b + a); }
elseif (s.equals("-")) { inta= deque.pop(), b = deque.pop(); deque.push(b - a); }
elseif (s.equals("*")) { inta= deque.pop(), b = deque.pop(); deque.push(b * a); }
elseif (s.equals("/")) { inta= deque.pop(), b = deque.pop(); deque.push(b / a); }
else deque.push(Integer.parseInt(s));
}
return deque.pop();
}
}
239. 滑动窗口最大值
classSolution {
publicint[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> deque = newArrayDeque<>();
intlen= nums.length, index = 0;
int[] res = newint[len - k + 1];
for (inti=0; i < len; i++) {
while (!deque.isEmpty() && deque.peek() < i - k + 1) deque.poll();
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) deque.pollLast();
deque.offer(i);
if (i >= k - 1) res[index++] = nums[deque.peek()];
}
return res;
}
}
347. 前 K 个高频元素
classSolution {
publicint[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = newHashMap<>();
for (int num : nums) map.put(num, map.getOrDefault(num, 0) + 1);
PriorityQueue<int[]> pq = newPriorityQueue<>((a, b) -> b[1] - a[1]);
for (Map.Entry<Integer, Integer> entry : map.entrySet()) pq.add(newint[]{entry.getKey(), entry.getValue()});
int[] res = newint[k];
for (inti=0; i < k; i++) res[i] = pq.poll()[0];
return res;
}
}
二叉树
144. 二叉树的前序遍历
classSolution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = newArrayList<>();
Deque<TreeNode> deque = newLinkedList<>();
if (root != null) deque.push(root);
while (!deque.isEmpty()) {
TreeNodenode= deque.peek();
if (node != null) {
deque.pop();
if (node.right != null) deque.push(node.right);
if (node.left != null) deque.push(node.left);
deque.push(node); deque.push(null);
} else {
deque.pop(); node = deque.peek(); deque.pop(); res.add(node.val);
}
}
return res;
}
}
94. 二叉树的中序遍历
classSolution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = newArrayList<>();
Deque<TreeNode> deque = newLinkedList<>();
if (root != null) deque.push(root);
while (!deque.isEmpty()) {
TreeNodenode= deque.peek();
if (node != null) {
deque.pop();
if (node.right != null) deque.push(node.right);
deque.push(node); deque.push(null);
if (node.left != null) deque.push(node.left);
} else {
deque.pop(); res.add(deque.pop().val);
}
}
return res;
}
}
145. 二叉树的后序遍历
classSolution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = newArrayList<>();
Deque<TreeNode> deque = newLinkedList<>();
if (root != null) deque.push(root);
while (!deque.isEmpty()) {
TreeNodenode= deque.peek();
if (node != null) {
deque.pop();
deque.push(node); deque.push(null);
if (node.right != null) deque.push(node.right);
if (node.left != null) deque.push(node.left);
} else {
deque.pop(); res.add(deque.pop().val);
}
}
return res;
}
}
102. 二叉树的层序遍历
classSolution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> resList = newArrayList<>();
if (root == null) return resList;
Queue<TreeNode> queue = newLinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
List<Integer> list = newArrayList<>();
intlen= queue.size();
while (len > 0) {
TreeNodecur= queue.poll();
list.add(cur.val);
if (cur.left != null) queue.offer(cur.left);
if (cur.right != null) queue.offer(cur.right);
len--;
}
resList.add(list);
}
return resList;
}
}
107. 二叉树的层序遍历 II
classSolution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> resList = newArrayList<>();
Deque<List<Integer>> stack = newLinkedList<>();
if (root == null) return resList;
Deque<TreeNode> deque = newLinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
List<Integer> list = newArrayList<>();
intlen= deque.size();
while (len > 0) {
TreeNodetemp= deque.poll();
list.add(temp.val);
if (temp.left != null) deque.offer(temp.left);
if (temp.right != null) deque.offer(temp.right);
len--;
}
stack.push(list);
}
while (!stack.isEmpty()) resList.add(stack.pop());
return resList;
}
}
199. 二叉树的右视图
classSolution {
public List<Integer> rightSideView(TreeNode root) {
List<Integer> res = newArrayList<>();
if (root == null) return res;
Deque<TreeNode> deque = newLinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
intlen= deque.size();
while (len > 0) {
TreeNodecur= deque.poll();
if (len == 1) res.add(cur.val);
if (cur.left != null) deque.offer(cur.left);
if (cur.right != null) deque.offer(cur.right);
len--;
}
}
return res;
}
}
429. N 叉树的层序遍历
classSolution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> resList = newArrayList<>();
if (root == null) return resList;
Deque<Node> deque = newLinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
List<Integer> list = newArrayList<>();
intlen= deque.size();
for (inti=0; i < len; i++) {
Nodetemp= deque.poll();
list.add(temp.val);
if (temp.children != null) for (Node child : temp.children) if (child != null) deque.offer(child);
}
resList.add(list);
}
return resList;
}
}
104. 二叉树的最大深度
classSolution {
publicintmaxDepth(TreeNode root) {
intdepth=0;
if (root == null) return depth;
Deque<TreeNode> deque = newLinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
intlen= deque.size();
while (len > 0) {
TreeNodetemp= deque.poll();
if (len == 1) depth++;
if (temp.left != null) deque.offer(temp.left);
if (temp.right != null) deque.offer(temp.right);
len--;
}
}
return depth;
}
}
111. 二叉树的最小深度
classSolution {
publicintminDepth(TreeNode root) {
intdepth=0;
if (root == null) return depth;
Deque<TreeNode> deque = newLinkedList<>();
deque.offer(root);
while (!deque.isEmpty()) {
intlen= deque.size();
while (len > 0) {
TreeNodetemp= deque.poll();
if (temp.left == null && temp.right == null) { depth++; return depth; }
if (len == 1) depth++;
if (temp.left != null) deque.offer(temp.left);
if (temp.right != null) deque.offer(temp.right);
len--;
}
}
return depth;
}
}
classSolution {
List<List<Integer>> res = newArrayList<>();
List<Integer> path = newLinkedList<>();
public List<List<Integer>> combine(int n, int k) {
backTracking(n, k, 1);
return res;
}
privatevoidbackTracking(int n, int k, int startIndex) {
if (path.size() == k) { res.add(newArrayList<>(path)); return; }
for (inti= startIndex; i <= n - (k - path.size()) + 1; i++) {
path.add(i);
backTracking(n, k, i + 1);
path.removeLast();
}
}
}
216. 组合总和 III
classSolution {
List<List<Integer>> res = newArrayList<>();
List<Integer> path = newLinkedList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
backTracking(k, n, 1);
return res;
}
privatevoidbackTracking(int k, int n, int startIndex) {
if (path.size() == k && n == 0) { res.add(newArrayList<>(path)); return; }
for (inti= startIndex; i <= 9; i++) {
if (n - i < 0) break;
path.add(i);
backTracking(k, n - i, i + 1);
path.removeLast();
}
}
}
17. 电话号码的字母组合
classSolution {
privatestaticfinal Map<Character, String> map = newHashMap<>();
private List<String> res = newArrayList<>();
privateStringBuildersb=newStringBuilder();
static { map.put('2', "abc"); map.put('3', "def"); map.put('4', "ghi"); map.put('5', "jkl"); map.put('6', "mno"); map.put('7', "pqrs"); map.put('8', "tuv"); map.put('9', "wxyz"); }
public List<String> letterCombinations(String digits) {
if (digits.length() == 0) return res;
backTracking(digits, 0);
return res;
}
privatevoidbackTracking(String digits, int startIndex) {
if (sb.length() == digits.length()) { res.add(newString(sb)); return; }
for (inti= startIndex; i < digits.length(); i++) {
Stringletters= map.get(digits.charAt(i));
for (char c : letters.toCharArray()) {
sb.append(c);
backTracking(digits, i + 1);
sb.deleteCharAt(sb.length() - 1);
}
}
}
}
39. 组合总和
classSolution {
List<List<Integer>> res = newArrayList<>();
List<Integer> path = newLinkedList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
backTracking(candidates, target, 0);
return res;
}
privatevoidbackTracking(int[] candidates, int target, int startIndex) {
if (target == 0) { res.add(newArrayList<>(path)); return; }
for (inti= startIndex; i < candidates.length; i++) {
if (candidates[i] > target) break;
path.add(candidates[i]);
backTracking(candidates, target - candidates[i], i);
path.removeLast();
}
}
}
40. 组合总和 II
classSolution {
List<List<Integer>> res = newArrayList<>();
List<Integer> path = newLinkedList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
backTracking(candidates, target, 0);
return res;
}
privatevoidbackTracking(int[] candidates, int target, int startIndex) {
if (target == 0) { res.add(newArrayList<>(path)); return; }
for (inti= startIndex; i < candidates.length; i++) {
if (candidates[i] > target) break;
if (i > startIndex && candidates[i] == candidates[i - 1]) continue;
path.add(candidates[i]);
backTracking(candidates, target - candidates[i], i + 1);
path.removeLast();
}
}
}
131. 分割回文串
classSolution {
List<List<String>> res = newArrayList<>();
List<String> path = newLinkedList<>();
public List<List<String>> partition(String s) {
backTracking(s, 0, newStringBuilder());
return res;
}
privatevoidbackTracking(String s, int startIndex, StringBuilder sb) {
if (startIndex == s.length()) { res.add(newArrayList<>(path)); return; }
for (inti= startIndex; i < s.length(); i++) {
sb.append(s.charAt(i));
if (check(sb)) { path.add(sb.toString()); backTracking(s, i + 1, newStringBuilder()); path.removeLast(); }
}
}
privatebooleancheck(StringBuilder sb) {
for (inti=0; i < sb.length() / 2; i++) if (sb.charAt(i) != sb.charAt(sb.length() - 1 - i)) returnfalse;
returntrue;
}
}
78. 子集
classSolution {
List<List<Integer>> res = newArrayList<>();
List<Integer> path = newLinkedList<>();
public List<List<Integer>> subsets(int[] nums) {
backTracking(nums, 0);
return res;
}
privatevoidbackTracking(int[] nums, int startIndex) {
res.add(newLinkedList<>(path));
if (startIndex == nums.length) return;
for (inti= startIndex; i < nums.length; i++) {
path.add(nums[i]);
backTracking(nums, i + 1);
path.removeLast();
}
}
}
90. 子集 II
classSolution {
List<List<Integer>> res = newArrayList<>();
List<Integer> path = newLinkedList<>();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
backTracking(nums, 0);
return res;
}
privatevoidbackTracking(int[] nums, int startIndex) {
res.add(newLinkedList<>(path));
for (inti= startIndex; i < nums.length; i++) {
if (i > startIndex && nums[i] == nums[i - 1]) continue;
path.add(nums[i]);
backTracking(nums, i + 1);
path.removeLast();
}
}
}
46. 全排列
classSolution {
List<List<Integer>> res = newArrayList<>();
List<Integer> path = newLinkedList<>();
boolean[] used;
public List<List<Integer>> permute(int[] nums) {
used = newboolean[nums.length];
backTracking(nums);
return res;
}
privatevoidbackTracking(int[] nums) {
if (path.size() == nums.length) { res.add(newArrayList<>(path)); return; }
for (inti=0; i < nums.length; i++) {
if (used[i]) continue;
used[i] = true; path.add(nums[i]);
backTracking(nums);
path.removeLast(); used[i] = false;
}
}
}
47. 全排列 II
classSolution {
List<List<Integer>> res = newArrayList<>();
List<Integer> path = newLinkedList<>();
public List<List<Integer>> permuteUnique(int[] nums) {
boolean[] used = newboolean[nums.length];
Arrays.sort(nums);
backTracking(nums, used);
return res;
}
privatevoidbackTracking(int[] nums, boolean[] used) {
if (path.size() == nums.length) { res.add(newArrayList<>(path)); return; }
for (inti=0; i < nums.length; i++) {
if (used[i]) continue;
if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) continue;
used[i] = true; path.add(nums[i]);
backTracking(nums, used);
path.removeLast(); used[i] = false;
}
}
}
22. 括号生成
classSolution {
List<String> res = newArrayList<>();
public List<String> generateParenthesis(int n) {
if (n <= 0) return res;
generateParenthesis(newStringBuilder(), n, n);
return res;
}
privatevoidgenerateParenthesis(StringBuilder path, int left, int right) {
if (left == 0 && right == 0) { res.add(path.toString()); return; }
if (left == right) { path.append('('); generateParenthesis(path, left - 1, right); path.deleteCharAt(path.length() - 1); }
elseif (left < right) {
if (left > 0) { path.append('('); generateParenthesis(path, left - 1, right); path.deleteCharAt(path.length() - 1); }
path.append(')'); generateParenthesis(path, left, right - 1); path.deleteCharAt(path.length() - 1);
}
}
}
79. 单词搜索
classSolution {
int len, height;
int[][] direction = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
publicbooleanexist(char[][] board, String word) {
height = board.length; len = board[0].length;
boolean[][] used = newboolean[height][len];
for (inti=0; i < height; i++) for (intj=0; j < len; j++) if (backTracking(board, i, j, word, 0, used)) returntrue;
returnfalse;
}
privatebooleanbackTracking(char[][] board, int i, int j, String word, int index, boolean[][] used) {
if (board[i][j] != word.charAt(index)) returnfalse;
elseif (index == word.length() - 1) returntrue;
used[i][j] = true;
booleanres=false;
for (int[] dir : direction) {
intnextI= i + dir[0], nextJ = j + dir[1];
if (nextI >= 0 && nextI < height && nextJ >= 0 && nextJ < len && !used[nextI][nextJ]) {
if (backTracking(board, nextI, nextJ, word, index + 1, used)) { res = true; break; }
}
}
used[i][j] = false;
return res;
}
}
51. N 皇后
classSolution {
List<List<String>> res = newArrayList<>();
public List<List<String>> solveNQueens(int n) {
char[][] board = newchar[n][n];
for (char[] ch : board) Arrays.fill(ch, '.');
backTracking(board, 0, n);
return res;
}
privatevoidbackTracking(char[][] board, int row, int n) {
if (row == n) { res.add(construct(board)); return; }
for (intcol=0; col < n; col++) {
if (isValid(board, row, col, n)) {
board[row][col] = 'Q';
backTracking(board, row + 1, n);
board[row][col] = '.';
}
}
}
privatebooleanisValid(char[][] board, int row, int col, int n) {
for (inti=0; i < row; i++) if (board[i][col] == 'Q') returnfalse;
for (inti= row - 1, j = col + 1; i >= 0 && j < n; i--, j--) if (board[i][j] == 'Q') returnfalse;
for (inti= row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) if (board[i][j] == 'Q') returnfalse;
returntrue;
}
private List<String> construct(char[][] board) {
List<String> ans = newArrayList<>();
for (char[] ch : board) ans.add(newString(ch));
return ans;
}
}
import java.util.*;
publicclassMain {
static List<List<Integer>> result = newArrayList<>();
static List<Integer> path = newArrayList<>();
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intn= scan.nextInt(), m = scan.nextInt();
int[][] graph = newint[n + 1][n + 1];
for (inti=0; i < m; i++) graph[scan.nextInt()][scan.nextInt()] = 1;
path.add(1);
dfs(graph, 1, n);
if (result.size() == 0) System.out.println(-1);
for (List<Integer> temp : result) {
for (inti=0; i < temp.size() - 1; i++) System.out.print(temp.get(i) + " ");
System.out.println(temp.get(temp.size() - 1));
}
}
publicstaticvoiddfs(int[][] graph, int x, int n) {
if (x == n) { result.add(newArrayList<>(path)); return; }
for (inti=1; i <= n; i++) {
if (graph[x][i] == 1) { path.add(i); dfs(graph, i, n); path.remove(path.size() - 1); }
}
}
}
98. 所有可达路径(图的 DFS 经典题目)【邻接表存储图】
import java.util.*;
publicclassMain {
static List<List<Integer>> result = newArrayList<>();
static List<Integer> path = newArrayList<>();
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intn= scan.nextInt(), m = scan.nextInt();
List<LinkedList<Integer>> graph = newArrayList<>();
for (inti=0; i <= n; i++) graph.add(newLinkedList<>());
while (m-- > 0) graph.get(scan.nextInt()).add(scan.nextInt());
path.add(1);
dfs(graph, 1, n);
if (result.isEmpty()) System.out.println(-1);
for (List<Integer> temp : result) {
for (inti=0; i < temp.size() - 1; i++) System.out.print(temp.get(i) + " ");
System.out.println(temp.get(temp.size() - 1));
}
}
publicstaticvoiddfs(List<LinkedList<Integer>> graph, int x, int n) {
if (x == n) { result.add(newArrayList<>(path)); return; }
for (int i : graph.get(x)) { path.add(i); dfs(graph, i, n); path.remove(path.size() - 1); }
}
}
99. 岛屿数量(广搜方法)
import java.util.*;
publicclassMain {
staticint[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intn= scan.nextInt(), m = scan.nextInt();
int[][] map = newint[n][m];
for (inti=0; i < n; i++) for (intj=0; j < m; j++) map[i][j] = scan.nextInt();
boolean[][] visit = newboolean[n][m];
intans=0;
for (inti=0; i < n; i++) for (intj=0; j < m; j++) if (!visit[i][j] && map[i][j] == 1) { ans++; bfs(map, visit, i, j); }
System.out.println(ans);
}
publicstaticvoidbfs(int[][] map, boolean[][] visit, int x, int y) {
Deque<int[]> queue = newLinkedList<>();
queue.add(newint[]{x, y});
visit[x][y] = true;
while (!queue.isEmpty()) {
int[] cur = queue.pop();
for (inti=0; i < 4; i++) {
intnextX= cur[0] + dir[i][0], nextY = cur[1] + dir[i][1];
if (nextX < 0 || nextX >= map.length || nextY < 0 || nextY >= map[0].length) continue;
if (map[nextX][nextY] == 1 && !visit[nextX][nextY]) { queue.push(newint[]{nextX, nextY}); visit[nextX][nextY] = true; }
}
}
}
}
99. 岛屿数量(深搜方法)
import java.util.*;
publicclassMain {
staticint[][] dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intN= scan.nextInt(), M = scan.nextInt();
int[][] grid = newint[N][M];
boolean[][] visit = newboolean[N][M];
for (inti=0; i < N; i++) for (intj=0; j < M; j++) grid[i][j] = scan.nextInt();
intans=0;
for (inti=0; i < N; i++) for (intj=0; j < M; j++) if (!visit[i][j] && grid[i][j] == 1) { ans++; visit[i][j] = true; dfs(grid, visit, i, j); }
System.out.println(ans);
}
privatestaticvoiddfs(int[][] grid, boolean[][] visit, int x, int y) {
for (inti=0; i < 4; i++) {
intnextX= x + dir[i][0], nextY = y + dir[i][1];
if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) continue;
if (!visit[nextX][nextY] && grid[nextX][nextY] == 1) { visit[nextX][nextY] = true; dfs(grid, visit, nextX, nextY); }
}
}
}
100. 最大岛屿的面积(深搜方法)
import java.util.*;
publicclassMain {
staticint[][] dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
staticintresult=0, count = 0;
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intN= scan.nextInt(), M = scan.nextInt();
int[][] grid = newint[N][M];
boolean[][] visit = newboolean[N][M];
for (inti=0; i < N; i++) for (intj=0; j < M; j++) grid[i][j] = scan.nextInt();
for (inti=0; i < N; i++) for (intj=0; j < M; j++) if (!visit[i][j] && grid[i][j] == 1) { count = 0; dfs(grid, visit, i, j); result = Math.max(result, count); }
System.out.println(result);
}
privatestaticvoiddfs(int[][] grid, boolean[][] visit, int x, int y) {
if (visit[x][y] || grid[x][y] == 0) return;
count++; visit[x][y] = true;
for (inti=0; i < 4; i++) {
intnextX= x + dir[i][0], nextY = y + dir[i][1];
if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) continue;
dfs(grid, visit, nextX, nextY);
}
}
}
100. 最大岛屿的面积(广搜方法)
import java.util.*;
publicclassMain {
staticint[][] dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
staticintresult=0, count = 0;
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intN= scan.nextInt(), M = scan.nextInt();
int[][] grid = newint[N][M];
boolean[][] visit = newboolean[N][M];
for (inti=0; i < N; i++) for (intj=0; j < M; j++) grid[i][j] = scan.nextInt();
for (inti=0; i < N; i++) for (intj=0; j < M; j++) if (!visit[i][j] && grid[i][j] == 1) { count = 0; bfs(grid, visit, i, j); result = Math.max(result, count); }
System.out.println(result);
}
privatestaticvoidbfs(int[][] grid, boolean[][] visit, int x, int y) {
Deque<int[]> deque = newLinkedList<>();
deque.push(newint[]{x, y});
count++; visit[x][y] = true;
while (!deque.isEmpty()) {
int[] cur = deque.pop();
for (inti=0; i < 4; i++) {
intnextX= cur[0] + dir[i][0], nextY = cur[1] + dir[i][1];
if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) continue;
if (!visit[nextX][nextY] && grid[nextX][nextY] == 1) { deque.push(newint[]{nextX, nextY}); visit[nextX][nextY] = true; count++; }
}
}
}
}
101. 孤岛的总面积
import java.util.*;
publicclassMain {
staticint[][] dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
staticbooleanisEdge=false, s = 0;
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intN= scan.nextInt(), M = scan.nextInt();
int[][] grid = newint[N][M];
boolean[][] visit = newboolean[N][M];
for (inti=0; i < N; i++) for (intj=0; j < M; j++) grid[i][j] = scan.nextInt();
intresult=0;
for (inti=0; i < N; i++) for (intj=0; j < M; j++) if (!visit[i][j] && grid[i][j] == 1) { isEdge = false; s = 0; dfs(grid, visit, i, j); if (!isEdge) result += s; }
System.out.println(result);
}
privatestaticvoiddfs(int[][] grid, boolean[][] visit, int x, int y) {
if (visit[x][y] || grid[x][y] == 0) return;
s++; visit[x][y] = true;
for (inti=0; i < 4; i++) {
intnextX= x + dir[i][0], nextY = y + dir[i][1];
if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) { isEdge = true; continue; }
dfs(grid, visit, nextX, nextY);
}
}
}
102. 沉没孤岛
import java.util.*;
publicclassMain {
staticint[][] dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intN= scan.nextInt(), M = scan.nextInt();
int[][] grid = newint[N][M];
for (inti=0; i < N; i++) for (intj=0; j < M; j++) grid[i][j] = scan.nextInt();
for (inti=0; i < N; i++) { if (grid[i][0] == 1) dfs(grid, i, 0); if (grid[i][M - 1] == 1) dfs(grid, i, M - 1); }
for (inti=0; i < M; i++) { if (grid[0][i] == 1) dfs(grid, 0, i); if (grid[N - 1][i] == 1) dfs(grid, N - 1, i); }
for (inti=0; i < N; i++) for (intj=0; j < M; j++) { if (grid[i][j] == 1) grid[i][j] = 0; if (grid[i][j] == 2) grid[i][j] = 1; }
for (inti=0; i < N; i++) { for (intj=0; j < M; j++) System.out.print(grid[i][j] + " "); System.out.println(); }
}
privatestaticvoiddfs(int[][] grid, int x, int y) {
if (grid[x][y] == 2 || grid[x][y] == 0) return;
grid[x][y] = 2;
for (inti=0; i < 4; i++) {
intnextX= x + dir[i][0], nextY = y + dir[i][1];
if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) continue;
dfs(grid, nextX, nextY);
}
}
}
103. 水流问题
import java.util.*;
publicclassMain {
staticint[][] dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intn= scan.nextInt(), m = scan.nextInt();
int[][] height = newint[n][m];
for (inti=0; i < n; i++) for (intj=0; j < m; j++) height[i][j] = scan.nextInt();
boolean[][] first = newboolean[n][m], second = newboolean[n][m];
for (inti=0; i < n; i++) { dfs(height, first, i, 0, Integer.MIN_VALUE); dfs(height, second, i, m - 1, Integer.MIN_VALUE); }
for (inti=0; i < m; i++) { dfs(height, first, 0, i, Integer.MIN_VALUE); dfs(height, second, n - 1, i, Integer.MIN_VALUE); }
List<List<Integer>> result = newArrayList<>();
for (inti=0; i < n; i++) for (intj=0; j < m; j++) if (first[i][j] && second[i][j]) result.add(Arrays.asList(i, j));
for (List<Integer> list : result) { for (inti=0; i < list.size(); i++) System.out.print(list.get(i) + (i == list.size() - 1 ? "" : " ")); System.out.println(); }
}
publicstaticvoiddfs(int[][] height, boolean[][] visit, int x, int y, int preHeight) {
if (x < 0 || x >= height.length || y < 0 || y >= height[0].length) return;
if (height[x][y] < preHeight || visit[x][y]) return;
visit[x][y] = true;
for (inti=0; i < 4; i++) dfs(height, visit, x + dir[i][0], y + dir[i][1], height[x][y]);
}
}
104. 建造最大岛屿
import java.util.*;
publicclassMain {
staticint mark, count;
staticint[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intn= scan.nextInt(), m = scan.nextInt();
int[][] grid = newint[n][m];
boolean[][] visit = newboolean[n][m];
for (inti=0; i < n; i++) for (intj=0; j < m; j++) grid[i][j] = scan.nextInt();
mark = 2;
Map<Integer, Integer> size = newHashMap<>();
booleanisAllIsland=true;
for (inti=0; i < n; i++) for (intj=0; j < m; j++) {
if (grid[i][j] == 0) isAllIsland = false;
if (grid[i][j] == 1) { count = 0; dfs(grid, visit, i, j); size.put(mark, count); mark++; }
}
intresult= isAllIsland ? m * n : 0;
Set<Integer> set = newHashSet<>();
for (inti=0; i < n; i++) for (intj=0; j < m; j++) if (grid[i][j] == 0) {
set.clear(); intcurSize=1;
for (int[] dir : dirs) {
intcurX= i + dir[0], curY = j + dir[1];
if (curX < 0 || curX >= n || curY < 0 || curY >= m) continue;
intcurMark= grid[curX][curY];
if (set.contains(curMark) || !size.containsKey(curMark)) continue;
curSize += size.get(curMark); set.add(curMark);
}
result = Math.max(curSize, result);
}
System.out.println(result);
}
publicstaticvoiddfs(int[][] grid, boolean[][] visit, int x, int y) {
count++; visit[x][y] = true; grid[x][y] = mark;
for (int[] dir : dirs) {
intnextX= x + dir[0], nextY = y + dir[1];
if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) continue;
if (grid[nextX][nextY] == 0 || visit[nextX][nextY]) continue;
dfs(grid, visit, nextX, nextY);
}
}
}
106. 岛屿的周长
import java.util.*;
publicclassMain {
staticint[][] dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
staticint count;
publicstaticvoidmain(String[] args) {
Scannerscan=newScanner(System.in);
intn= scan.nextInt(), m = scan.nextInt();
int[][] grid = newint[n][m];
for (inti=0; i < n; i++) for (intj=0; j < m; j++) grid[i][j] = scan.nextInt();
intresult=0;
for (inti=0; i < n; i++) for (intj=0; j < m; j++) if (grid[i][j] == 1) { count = 0; sum(grid, i, j); result += count; }
System.out.println(result);
}
publicstaticvoidsum(int[][] grid, int x, int y) {
for (int[] di : dir) {
intnextX= x + di[0], nextY = y + di[1];
if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length || grid[nextX][nextY] == 0) count++;
}
}
}