算法模版,今天开始背

  1. 二分查找算法

    int left_bound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    // 搜索区间为 [left, right]
    while (left <= right) {
    int mid = left + (right - left) / 2;
    if (nums[mid] < target) {
    // 搜索区间变为 [mid+1, right]
    left = mid + 1;
    } else if (nums[mid] > target) {
    // 搜索区间变为 [left, mid-1]
    right = mid - 1;
    } else if (nums[mid] == target) {
    // 收缩右侧边界
    right = mid - 1;
    }
    }
    // 判断 target 是否存在于 nums 中
    // 如果越界,target 肯定不存在,返回 -1
    if (left < 0 || left >= nums.length) {
    return -1;
    }
    // 判断一下 nums[left] 是不是 target
    return nums[left] == target ? left : -1;
    }

  2. 滑动窗口算法

上下是对称的

/* 滑动窗口算法框架 */
void slidingWindow(String s) {
    // 用合适的数据结构记录窗口中的数据
    HashMap<Character, Integer> window = new HashMap<>();

    int left = 0, right = 0;
    while (right < s.length()) {
        // c 是将移入窗口的字符
        char c = s.charAt(right);
        window.put(c, window.getOrDefault(c, 0) + 1);
        // 增大窗口
        right++;
        // 进行窗口内数据的一系列更新
        ...

        /*** debug 输出的位置 ***/
        // 注意在最终的解法代码中不要 print
        // 因为 IO 操作很耗时,可能导致超时
        System.out.printf("window: [%d, %d)\n", left, right);
        /********************/

        // 判断左侧窗口是否要收缩
        while (left < right && window needs shrink) {
            // d 是将移出窗口的字符
            char d = s.charAt(left);
            window.put(d, window.get(d) - 1);
            // 缩小窗口
            left++;
            // 进行窗口内数据的一系列更新
            ...
        }
    }
}
  1. 二叉树的层序遍历

    // 输入一棵二叉树的根节点,层序遍历这棵二叉树
    void levelTraverse(TreeNode root) {
    if (root == null) return;
    Queue<TreeNode> q = new LinkedList<>();
    q.offer(root);

     // 从上到下遍历二叉树的每一层
     while (!q.isEmpty()) {
         int sz = q.size();
         // 从左到右遍历每一层的每个节点
         for (int i = 0; i < sz; i++) {
             TreeNode cur = q.poll();
             // 将下一层节点放入队列
             if (cur.left != null) {
                 q.offer(cur.left);
             }
             if (cur.right != null) {
                 q.offer(cur.right);
             }
         }
     }
    

    }

  2. 动态规划算法

    以最小硬币数为例
    class Solution {
    int[] memo;

     int coinChange(int[] coins, int amount) {
         memo = new int[amount + 1];
         // 备忘录初始化为一个不会被取到的特殊值,代表还未被计算
         Arrays.fill(memo, -666);
    
         return dp(coins, amount);
     }
    
     int dp(int[] coins, int amount) {
         if (amount == 0) return 0;
         if (amount < 0) return -1;
         // 查备忘录,防止重复计算
         if (memo[amount] != -666)
             return memo[amount];
    
         int res = Integer.MAX_VALUE;
         for (int coin : coins) {
             // 计算子问题的结果
             int subProblem = dp(coins, amount - coin);
             // 子问题无解则跳过
             if (subProblem == -1) continue;
             // 在子问题中选择最优解,然后加一
             res = Math.min(res, subProblem + 1);
         }
         // 把计算结果存入备忘录
         memo[amount] = (res == Integer.MAX_VALUE) ? -1 : res;
         return memo[amount];
     }
    

    }

  3. Nsum问题

    class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
    Arrays.sort(nums);
    return nSum(nums,4,0,target);
    }

     public List<List<Integer>> nSum(int[] nums, int n, int start , long target){
         List<List<Integer>> result = new ArrayList<>();
         if(n==2){
             int left = start;
             int right = nums.length -1 ;
             while(left<right){
                 int leftValue = nums[left];
                 int rightValue = nums[right];
                 int sum = leftValue + rightValue;
                 if(sum==target){
                     List<Integer> collect = new ArrayList<>();
                     collect.add(leftValue);
                     collect.add(rightValue);
                     result.add(collect);    
                     while(left<right&&nums[left]==leftValue) left++;
                     while(left<right&&nums[right]==rightValue) right--;       
                 }else if( sum > target){
                     right--;
                      while(left<right&&nums[right]==rightValue) right--;  
                 }else{
                     left++;
                     while(left<right&&nums[left]==leftValue) left++;
    
                 }
             }
         }else{
             for(int i = start;i<nums.length;i++){
                 List<List<Integer>> temp = nSum(nums,n-1,i+1,target-nums[i]);
                 for(List<Integer> list : temp){
                     list.add(nums[i]);
                     result.add(list);
                 }
                 while(i<nums.length-1&&nums[i]==nums[i+1]) i++;
             }
         }
         return result;
     }
    

    }

相关推荐
Abelard_2 分钟前
LeetCode--347.前k个高频元素(使用优先队列解决)
java·算法·leetcode
小猪写代码5 分钟前
C语言:递归函数(新增)
算法·c#
点云SLAM7 分钟前
C++创建文件夹和文件夹下相关操作
开发语言·c++·算法
海海不掉头发18 分钟前
软件工程-【软件项目管理】--期末复习题汇总
java·学习·产品运营·软件工程·团队开发·需求分析·期末复习
缘友一世21 分钟前
java实现网络IO高并发编程java AIO
java·网络·python
CodeClimb25 分钟前
【华为OD-E卷 - 猜字谜100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
ADRU31 分钟前
设计模式-责任链模式
java·设计模式·责任链模式
heeheeai32 分钟前
kotlin 函数作为参数
java·算法·kotlin
是十一月末42 分钟前
opencv实现KNN算法识别图片数字
人工智能·python·opencv·算法·k-近邻算法
袖清暮雨1 小时前
5_SparkGraphX讲解
大数据·算法·spark