通用算法模板

本文详细介绍了几种常用的算法模板,包括二分查找的三种实现(普通二分、左边界查找、右边界查找)、BFS层次遍历二叉树、DFS回溯解决全排列问题,以及滑动窗口在字符串处理中的应用。这些算法在数据结构与算法学习中至关重要,对于提升编程能力具有显著效果。
摘要由CSDN通过智能技术生成

文章目录

二分查找

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值