算法题合集

import java.util.*;

public class Main{
    // Definition for a Node.
    class Node {
        public int val;
        public Node left;
        public Node right;
        public Node() {}
        public Node(int _val) {
            val = _val;
        }

        public Node(int _val,Node _left,Node _right) {
            val = _val;
            left = _left;
            right = _right;
        }
    };
    //删除排序链表中的重复节点
    public static ListNode deleteDuplicates(ListNode head) {
        ListNode p=head;
        ListNode q=head;
        while (q!=null){
            if (q.val==p.val){
                q=q.next;
            }else{
                //进行更新
                p.next=q;
                p=q;
            }
        }
        //将最后一部分
        p.next=q;
        return head;
    }

    Node head = new Node(-1);
    Node p=head;
    //将二叉搜索树转为链表-中序遍历
    public Node treeToDoublyList(Node root) {
        //开始进行遍历
        if (root == null) return null; // 空树直接返回 null
        tree(root); // 中序遍历构建双向链表

        // 处理循环连接
        Node first = head.right; // 真正的头节点
        Node last = p; // 此时的 p 指向最后一个节点
        // 首尾相连形成循环
        first.left = last;
        last.right = first;
        return first; // 返回真正的头节点,而不是哨兵节点
    }
    public void tree(Node root){
        if (root==null){
            return;
        }
        tree(root.left);
        //处理当前节点
        Node temp=root;
        //开始进行遍历
        p.right=temp;
        temp.left=p;
        p=p.right;
        tree(root.right);
    }

    //每日温度-超时方法
    public static int[] dailyTemperatures_1(int[] temperatures) {
        int n = temperatures.length;
        //建立一个数组
        int[] nums = new int[n];
        for (int i=0; i<n-1;i++){
            int count =1;
            int j=i+1;
            for (;j<n;j++){
                if (temperatures[j]>temperatures[i]){
                    break;
                }else{
                    count++;
                }
            }
            if (j==n){
                nums[i]=0;
            }else{
                nums[i]=count;
            }
        }
        return nums;
    }

    public static int[] dailyTemperatures(int[] temperatures) {
        int n = temperatures.length;
        int[] nums = new int[n];
        //从右向左进行比较
        for (int i=n-2;i>=0;i--){
            //向后移动
            for (int j=i+1;j<n;j+=nums[j]){
                if (temperatures[j]>temperatures[i]){
                    nums[i]=j-i;
                    break;
                }else if (nums[j]==0){
                    nums[i]=0;
                    break;
                }
            }
        }
        return nums;
    }
    //"catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
    //单间拆分-通过wordDict去组合s-采取递归
    public static boolean wordBreak(String s, List<String> wordDict) {
        return helper(s, wordDict, new HashMap<>());
    }

    private static boolean helper(String s, List<String> wordDict, Map<String, Boolean> memo) {
        if (s.isEmpty()) return true;
        if (memo.containsKey(s)) return memo.get(s); // 记忆化

        for (String word : wordDict) {
            if (s.startsWith(word)) {
                String newS = s.substring(word.length());
                if (helper(newS, wordDict, memo)) {
                    memo.put(s, true); // 缓存结果
                    return true;
                }
            }
        }

        memo.put(s, false); // 缓存结果
        return false;
    }

    //采取动态规划
    public static boolean wordBreak_1(String s, List<String> wordDict) {
        Set<String> wordSet = new HashSet<>(wordDict); // 用 HashSet 提高查询效率
        int n = s.length();
        boolean[] dp = new boolean[n + 1]; // dp[i] 表示 s[0..i-1] 是否能被拆分
        dp[0] = true; // 空字符串可以被拆分

        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < i; j++) {
                if (dp[j] && wordSet.contains(s.substring(j, i))) {
                    dp[i] = true;
                    break; // 找到一个拆分方式即可
                }
            }
        }
        return dp[n]; // 返回整个字符串的结果
    }
    // 7 4 8 9 3 2
    //归并排序
    public static int[] sortArray(int[] nums) {
        return sort(nums, 0, nums.length-1);
    }
    private static int[] sort(int[] nums, int left, int right) {
        if (left>=right){
            return new int[]{nums[left]};
        }
        int mid = (left+right)/2;
        int[] leftNum = sort(nums, left, mid);
        int[] rightNum = sort(nums,mid+1,right);
        return merge(leftNum, rightNum);
    }
    private static int[] merge(int[] leftNum, int[] rightNum) {
        //开始进行合并
        int[] res = new int[leftNum.length+rightNum.length];
        int i=0;
        int j=0;
        int k=0;
        while (i<leftNum.length&&j<rightNum.length){
            if (leftNum[i]<rightNum[j]){
                res[k++]=leftNum[i++];
            }else{
                res[k++]=rightNum[j++];
            }
        }
        while (i<leftNum.length){
            res[k++]=leftNum[i++];
        }
        while (j<rightNum.length){
            res[k++]=rightNum[j++];
        }
        return res;
    }
    //翻转二叉树-将二叉树进行翻转
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        TreeNode left = invertTree(root.getLeft());
        TreeNode right = invertTree(root.getRight());
        root.setLeft(right);
        root.setRight(left);
        return root;
    }
    static int res = Integer.MAX_VALUE;

    // 长度最小子数组
    public static int minSubArrayLen(int target, int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            findMin(target, nums, i, i, 0); // 新增一个参数 sum,初始值为 0
        }
        return res == Integer.MAX_VALUE ? 0 : res; // 如果没有找到满足条件的子数组,返回 0
    }

    public static void findMin(int target, int[] nums, int pos, int currentPos, int currentSum) {
        // 如果当前子数组的和已经大于等于目标值
        if (currentSum >= target) {
            res = Math.min(res, currentPos - pos + 1); // 更新最小子数组长度
            return; // 停止继续扩展当前子数组
        }

        // 如果已经超出数组范围,直接返回
        if (currentPos >= nums.length) {
            return;
        }
        // 累加当前元素到子数组的和
        currentSum += nums[currentPos];
        // 递归调用,扩展当前子数组
        findMin(target, nums, pos, currentPos + 1, currentSum);
    }

    //1 1 2 3 3
    public static void main(String[] args) {
        int[] nums1 = {2, 3, 1, 2, 4, 3};
        int target1 = 7;
        System.out.println(minSubArrayLen(target1, nums1)); // 输出 2

        int[] nums2 = {1, 4, 4};
        int target2 = 4;
        System.out.println(minSubArrayLen(target2, nums2)); // 输出 1

        int[] nums3 = {1, 1, 1, 1, 1, 1, 1, 1};
        int target3 = 11;
        System.out.println(minSubArrayLen(target3, nums3)); // 输出 0
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值