左程云大厂算法刷题班——03

第一题

在这里插入图片描述
思路:贪心 + 滑动窗口


public class 第一题03 {
    public static int maxPairNum(int[] arr,int k){
        if (k < 0 || arr == null || arr.length <= 1){
            return 0;
        }
        Arrays.sort(arr);
        int n = arr.length;
        int l = 0;
        int r = 0;
        boolean[] visit = new boolean[n];
        int ans = 0;
        while (r < n){
            if (visit[l]){
                l++;
            }else if (l == r){
                r++;
            }else {
                if (arr[r] - arr[l] == k){
                    ans++;
                    visit[r] = true;
                    l++;
                    r++;
                }else if (arr[r] - arr[l] > k){
                    l++;
                }else {
                    r++;
                }
            }
        }
        return ans;
    }
    public static void main(String[] args) {
        int[] arr = {1,1,2,4,6,8,6,9,3,3,5,7};
        int res = maxPairNum(arr, 2);
        System.out.println(res);
    }
}

第二题

在这里插入图片描述请添加图片描述

public class 第二题03 {
    public static int minBoot(int[] arr,int limit){
        if (arr == null || arr.length < 1){
            return 0;
        }
        int N = arr.length;
        Arrays.sort(arr);
        if (arr[N - 1] > limit){
            return -1;
        }
        int half_limit = limit / 2;
        int last_L = 0;
        int last_R = 0;
        for (int i = 0;i < N;i++){
            if (arr[i] > half_limit){
                last_L = i - 1;
                last_R = i;
                break;
            }
        }
        int ans = 0;
        int num_x = 0;
        while (last_L >= 0 && last_R < N){
            int sum = arr[last_L] + arr[last_R];
            if (sum > limit){
                last_L--;
                num_x++;
            }else if (sum <= limit){
                last_R++;
                last_L--;
                ans++;
            }
        }
        int res = ans + (num_x + 1) / 2 + (N - last_R);
        return res;
    }

    public static void main(String[] args) {
        int[] arr = {1,1,1,1,2,3,5,5,5,5,6,6,7,8,9,10};
        int res = minBoot(arr, 10);
        System.out.println(res);
    }
}

第三题

在这里插入图片描述

public class 第三题03 {
    public static int maxSum(int[] arr){
        if (arr == null || arr.length < 1){
            return 0;
        }
        int n = arr.length;
        int max = arr[0];
        int sum = 0;
        for (int i = 0;i < n;i++){
            if (sum < 0){
                sum = arr[i];
            }else {
                sum += arr[i];
            }
            max = Math.max(max,sum);
        }
        return max;
    }

    public static void main(String[] args) {
        int[] arr = {-3,4,-3,2,-1,1,6,-7};
        int res = maxSum(arr);
        System.out.println(res);
    }
}

第四题

leetcode135:分发糖果
进阶问题:
n个人参加比赛,结束后每个人一个分数。
领奖时所有人依次排成一圈,第一个和第n个相邻。
要求:
1.如果某个人的分数比旁边的人高,那么奖品数量也要比他多。
2.每个至少得一个奖品。
问最少应该准备多少个奖品?
进阶问题思路:化圈为直,找到数组中小于左右两边的数开始遍历,后面步骤同leetcode135

public class 第四题03 {
    //leetcode135:分发糖果
    public static int candy(int[] ratings){
        int n = ratings.length;
        int[] left_candy = new int[n];
        int[] right_candy = new int[n];
        Arrays.fill(left_candy,1);
        Arrays.fill(right_candy,1);
        for (int i = 1;i < n;i++){
            if (ratings[i] > ratings[i - 1]){
                left_candy[i] = left_candy[i - 1] + 1;
            }
        }
        for (int i = n - 2;i >= 0;i--){
            if (ratings[i] > ratings[i + 1]){
                right_candy[i] = right_candy[i + 1] + 1;
            }
        }
        int sum = 0;
        for (int i = 0;i < n;i++){
            sum += Math.max(left_candy[i],right_candy[i]);
        }
        return sum;
    }
    //进阶问题:小朋友做一圈,进行分发糖果,规则同上
    public static int candy_advance(int[] ratings){
        int n = ratings.length;
        int min_index = 0;
        for (int i = 0;i < n;i++){
            if (i == 0){
                if (ratings[i] <= ratings[n - 1] && ratings[i] <= ratings[i + 1]){
                    min_index = i;
                    break;
                }
            }else if (i == n - 1){
                if (ratings[i] <= ratings[0] && ratings[i] <= ratings[i - 1]){
                    min_index = i;
                    break;
                }
            }else {
                if (ratings[i] <= ratings[i + 1] && ratings[i] <= ratings[i - 1]){
                    min_index = i;
                    break;
                }
            }
        }
        int[] newRatings = new int[n + 1];
        System.arraycopy(ratings,min_index,newRatings,0,n - min_index);
        System.arraycopy(ratings,0,newRatings,n - min_index,min_index);
        newRatings[n] = ratings[min_index];

        int[] left_candy = new int[n];
        int[] right_candy = new int[n];
        Arrays.fill(left_candy,1);
        Arrays.fill(right_candy,1);
        for (int i = 1;i < n;i++){
            if (newRatings[i] > newRatings[i - 1]){
                left_candy[i] = newRatings[i - 1] + 1;
            }
        }
        for (int i = n - 2;i >= 0;i--){
            if (newRatings[i] > newRatings[i + 1]){
                right_candy[i] = right_candy[i + 1] + 1;
            }
        }
        int sum = 0;
        for (int i = 0;i < n;i++){
            sum += Math.max(left_candy[i],right_candy[i]);
        }
        return sum - 1;
    }
    public static void main(String[] args) {
        int[] ratings = {4,3,1,2,1,3};
        int res = candy_advance(ratings);
        System.out.println(res);
    }
}

第五题

leetcode97:交错字符串
思路:动态规划(类似路径查找)

public class 第五题03 {
    public static boolean isInterleave(String s1, String s2, String s3) {
        if (s3.length() > s1.length() + s2.length()){
            return false;
        }
        int n = s1.length();
        int m = s2.length();
        int k = s3.length();
        boolean[][] dp = new boolean[n + 1][m + 1];
        dp[0][0] = true;
        for (int i = 1;i < n && s1.charAt(i - 1) == s3.charAt(i - 1);i++){
            dp[i][0]= true;
        }
        for (int i = 1;i < m && s2.charAt(i - 1) == s3.charAt(i - 1);i++){
            dp[0][i] = true;
        }
        for (int i = 1;i <= n;i++){
            for (int j = 1;j <= m;j++){
                dp[i][j] = (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)
                        || (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1)));
            }
        }
        return dp[n][m];
    }
}

第六题

在这里插入图片描述
思路:递归:sum = 左边子树相等的数量 + 右边子树相等的数量 + 中间的左右子树是否相等 ?1 :0;

class TreeNode {
      int val;
      TreeNode left;
      TreeNode right;
      TreeNode() {}
      TreeNode(int val) { this.val = val; }
      TreeNode(int val, TreeNode left, TreeNode right) {
          this.val = val;
          this.left = left;
          this.right = right;
      }
  }
public class 第六题03 {
    public static int sameNumber(TreeNode head){
        if (head == null){
            return 0;
        }
        return sameNumber(head.left) + sameNumber(head.right) + (same(head.left,head.right) ? 1 : 0);
    }

    private static boolean same(TreeNode left, TreeNode right) {
        if (left == null && right == null){
            return true;
        }
        //判断一个为空,另一个不为空
//        if ((left == null && right != null) || left != null && right == null){
//            return false;
//        }
        if (left == null ^ right == null){//同上代码作用一样:判断一个为空,另一个不为空
            return false;
        }
        return left.val == right.val && same(left.left,right.left) && same(left.right,right.right);
    }
}

第七题

leetcode72

public static int minDistance(String word1, String word2) {
        int n = word1.length();
        int m = word2.length();
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 0;i <= m;i++){
            dp[i][0] = i;
        }
        for (int i = 0;i <= n;i++){
            dp[0][i] = i;
        }
        for (int i = 1;i <= m;i++){
            for (int j = 1;j <= n;j++){
                if (word1.charAt(j - 1) == word2.charAt(i - 1)){
                    dp[i][j] = dp[i - 1][j - 1];
                }else {
                    dp[i][j] = Math.min(dp[i - 1][j - 1],Math.min(dp[i - 1][j],dp[i][j - 1])) + 1;
                }
            }
        }
        return dp[m][n];
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值