文章目录
二分查找
public class binary {
// 二分搜索模板
int binary_search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if(nums[mid] == target) {
// 直接返回
return mid;
}
}
// 直接返回
return -1;
}
int left_bound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] == target) {
// 别返回,锁定左侧边界
right = mid - 1;
}
}
// 最后要检查 left 越界的情况
if (left >= nums.length || nums[left] != target)
return -1;
return left;
}
int right_bound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] == target) {
// 别返回,锁定右侧边界
left = mid + 1;
}
}
// 最后要检查 right 越界的情况
if (right < 0 || nums[right] != target)
return -1;
return right;
}
}
BFS
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Queue;
public class offer32_1 {
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
// bfs模板
public static int[] levelOrder(TreeNode root) {
if (root == null) return new int[]{};
Queue<TreeNode> queue = new ArrayDeque<>();
ArrayList<Integer> data = new ArrayList<>();
// 1. 父节点加入队列
queue.add(root);
while (queue.size() > 0) {
// 2. 层次遍历
int size = queue.size();
while (size >0) {
TreeNode cur = queue.poll();
// 3.添加数据
data.add(cur.val);
// 4.添加下层数据
if (cur.left!=null) queue.add(cur.left);
if (cur.right!=null) queue.add(cur.right);
size--;
}
}
// 5. 返回数据
int[] nums = new int[data.size()];
for (int i = 0; i < nums.length; i++) nums[i] = data.get(i);
return nums;
}
public static void main(String[] args) {
TreeNode root = new TreeNode(3);
root.left = new TreeNode(9);
root.right = new TreeNode(20);
root.right.left = new TreeNode(15);
root.right.right = new TreeNode(7);
System.out.println(levelOrder(root));
}
}
DFS(回溯)
import java.util.*;
public class sf10151 {
static List<List<Integer>> res = new ArrayList<>();
// 46
public static void main(String[] args) {
int[] nums = new int[] {1,2,3};
int len = nums.length;
// 回溯
LinkedList<Integer> data = new LinkedList<>();
recall(nums, data);
System.out.println(res);
// DFS
// List<List<Integer>> res = new ArrayList<>();
// Deque<Integer> path = new ArrayDeque<Integer>();
// boolean[] used = new boolean[len];
// dfs(nums, len, 0, path,used, res);
// System.out.println(res);
}
static void recall(int[] nums, LinkedList<Integer> data) {
// 1. 结束条件
if (data.size() == nums.length) {
res.add(new LinkedList<>(data));
return;
}
for (int i = 0; i < nums.length; i++) {
if (data.contains(nums[i])) continue;
// 2. 做选择
data.add(nums[i]);
recall(nums, data);
// 3. 撤销选择
data.removeLast();
}
}
static void dfs(int[] nums, int len, int depth, Deque<Integer> path, boolean[] used, List<List<Integer>> res) {
if (depth == len) {
res.add(new ArrayList<>(path));
return;
}
for (int i=0; i<len; i++) {
if (used[i]) {
continue;
}
path.addLast(nums[i]);
used[i] = true;
dfs(nums, len, depth+1, path,used, res);
path.removeLast();
used[i] = false;
}
}
}
二叉树遍历
void traverse(TreeNode root) {
// 前序遍历
traverse(root.left)
// 中序遍历
traverse(root.right)
// 后序遍历
}
BST遍历
void BST(TreeNode root, int target) {
if (root.val == target)
// 找到目标,做点什么
if (root.val < target)
BST(root.right, target);
if (root.val > target)
BST(root.left, target);
}
滑动窗口
import java.util.HashMap;
public class slide_window {
// 滑动窗口模板
static String minWindow(String s, String t) {
char[] data = t.toCharArray();
// 1. 初始化数据
HashMap<Character, Integer> need, window;
need = new HashMap<>();
window = new HashMap<>();
for (char c : data) need.put(c, 0);
int left = 0, right = 0;
int valid = 0;
// 记录最小覆盖子串的起始索引及长度
int start = 0, len = Integer.MAX_VALUE;
// 2.滑动窗口记录数据
while (right < s.length()) {
// c 是将移入窗口的字符
char c = s.charAt(right);
// 右移窗口
right++;
// 进行窗口内数据的一系列更新
if (need.containsValue(c)) {
window.put(c, window.get(c)+1);
if (window.get(c) == need.get(c))
valid++;
}
// 3.判断左侧窗口是否要收缩
while (valid == need.size()) {
// 在这里更新最小覆盖子串
if (right - left < len) {
start = left;
len = right - left;
}
// d 是将移出窗口的字符
char d = s.charAt(left);
// 左移窗口
left++;
// 进行窗口内数据的一系列更新
if (need.containsValue(d)) {
if (window.get(d) == need.get(d))
valid--;
window.put(c, window.get(d)-1);
}
}
}
// 4. 返回最小覆盖子串
return len == Integer.MAX_VALUE ?
"" : s.substring(start, len);
}
public static void main(String[] args) {
System.out.println(minWindow("a", "a"));
}
}
DP
TODO