Java每日一练(20230514) 滑动窗、最大子序和、转罗马数字

简介: Java每日一练(20230514) 滑动窗、最大子序和、转罗马数字

1. 滑动窗口最大值


给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。


返回滑动窗口中的最大值。


示例 1:

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3

输出:[3,3,5,5,6,7]

解释:

滑动窗口的位置                最大值

---------------               -----

[1 3  -1] -3  5  3  6  7       3

1 [3  -1  -3] 5  3  6  7       3

1  3 [-1  -3  5] 3  6  7       5

1  3  -1 [-3  5  3] 6  7       5

1  3  -1  -3 [5  3  6] 7       6

1  3  -1  -3  5 [3  6  7]      7


示例 2:

输入:nums = [1], k = 1

输出:[1]


示例 3:

输入:nums = [1,-1], k = 1

输出:[1,-1]


示例 4:

输入:nums = [9,11], k = 2

输出:[11]


示例 5:

输入:nums = [4,-2], k = 2

输出:[4]


提示:

   1 <= nums.length <= 10^5

   -10^4 <= nums[i] <= 10^4

   1 <= k <= nums.length

出处:

https://edu.csdn.net/practice/27810767

代码:

import java.util.*;
public class Solution5 {
    public static int[] maxSlidingWindow(int[] nums, int k) {
        if (nums == null || nums.length < 0 || k <= 0 || k == 1)
            return nums;
        PriorityQueue<Integer> queue = new PriorityQueue<>(k, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        int[] max = new int[nums.length - k + 1];
        for (int i = 0; i < nums.length; i++) {
            if (i < k - 1) {
                queue.add(nums[i]);
            } else if (i == k - 1) {
                queue.add(nums[i]);
                max[0] = queue.peek();
            } else {
                queue.remove(nums[i - k]);
                queue.add(nums[i]);
                max[i - k + 1] = queue.peek();
            }
        }
        return max;
    }
    public static void main(String[] args) {
        int[] nums = {1,3,-1,-3,5,3,6,7};
        System.out.println(Arrays.toString(maxSlidingWindow(nums, 3)));
    }
}

输出:

[3, 3, 5, 5, 6, 7]




2. 最大子序和


给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。


示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]

输出:6

解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。


示例 2:

输入:nums = [1]

输出:1


示例 3:

输入:nums = [0]

输出:0


示例 4:

输入:nums = [-1]

输出:-1


示例 5:

输入:nums = [-100000]

输出:-100000


提示:

   1 <= nums.length <= 3 * 10^4

   -10^5 <= nums[i] <= 10^5


进阶:如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的 分治法 求解。


出处:

https://edu.csdn.net/practice/27810768

代码1:

import java.util.*;
public class maxSubArray {
    public static int maxSubArray(int[] nums) {
        int maxSum = nums[0];
        int curSum = 0;
        for (int n : nums) {
            curSum += n;
            if (curSum > maxSum) {
                maxSum = curSum;
            }
            if (curSum < 0) {
                curSum = 0;
            }
        }
        return maxSum;
    }
    public static void main(String[] args) {
        int[] nums = {-2,1,-3,4,-1,2,1,-5,4};
        System.out.println(maxSubArray(nums));
    }
}


代码2:

import java.util.*;
public class maxSubArray {
    public static int maxSubArray(int[] nums) {
        int n = nums.length;
        int[] dp = new int[n];
        dp[0] = nums[0];
        int res = dp[0];
        for (int i = 1; i < n; i++) {
            dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);
            res = Math.max(res, dp[i]);
        }
        return res;
    }
    public static void main(String[] args) {
        int[] nums = {-2,1,-3,4,-1,2,1,-5,4};
        System.out.println(maxSubArray(nums));
    }
}



代码3:

import java.util.*;
public class maxSubArray {
    public static int maxSubArray(int[] nums) {
        return maxSubArrayHelper(nums, 0, nums.length-1);
    }
    public static int maxSubArrayHelper(int[] nums, int left, int right) {
        if (left == right) {
            return nums[left];
        }
        int mid = left + (right-left)/2;
        int leftMax = maxSubArrayHelper(nums, left, mid);
        int rightMax = maxSubArrayHelper(nums, mid+1, right);
        int crossMax = crossMaxSubArray(nums, left, right, mid);
        return Math.max(leftMax, Math.max(rightMax, crossMax));
    }
    public static int crossMaxSubArray(int[] nums, int left, int right, int mid) {
        int leftMax = Integer.MIN_VALUE;
        int curSum = 0;
        for (int i = mid; i >= left; i--) {
            curSum += nums[i];
            leftMax = Math.max(leftMax, curSum);
        }
        int rightMax = Integer.MIN_VALUE;
        curSum = 0;
        for (int i = mid+1; i <= right; i++) {
            curSum += nums[i];
            rightMax = Math.max(rightMax, curSum);
        }
        return leftMax + rightMax;
    }
    public static void main(String[] args) {
        int[] nums = {-2,1,-3,4,-1,2,1,-5,4};
        System.out.println(maxSubArray(nums));
    }
}

输出:

6


3. 整数转罗马数字


罗马数字包含以下七种字符: IVXLCDM


字符          数值

I             1

V             5

X             10

L             50

C             100

D             500

M             1000


例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。


通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:


   I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。

   X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。  

   C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。


给你一个整数,将其转为罗马数字。


示例 1:

输入: num = 3

输出: "III"


示例 2:

输入: num = 4

输出: "IV"


示例 3:

输入: num = 9

输出: "IX"


示例 4:

输入: num = 58

输出: "LVIII"

解释: L = 50, V = 5, III = 3.


示例 5:

输入: num = 1994

输出: "MCMXCIV"

解释: M = 1000, CM = 900, XC = 90, IV = 4.


提示:

   1 <= num <= 3999

出处:

https://edu.csdn.net/practice/27810769

代码:

import java.util.*;
public class Solution {
    public static String intToRoman(int num) {
        int f = 1000;
        int f2 = 1000;
        char[] sym = new char[] { 'M', 'D', 'C', 'L', 'X', 'V', 'I' };
        int fsi = 0;
        int[] s = new int[] { 2, 5 };
        int si = 0;
        int[] s2 = new int[] { 10, 1 };
        int si2 = 0;
        StringBuilder roman = new StringBuilder();
        while (num > 0) {
            int d = (int) Math.floor(num / f);
            int r = num % f;
            int d2 = (int) Math.floor(num / f2);
            int r2 = num % f2;
            if (d > 0) {
                if (d == 4) {
                    roman.append(sym[fsi]);
                    roman.append(sym[fsi - 1]);
                    num = r;
                } else if (d2 == 9) {
                    roman.append(sym[fsi + 1]);
                    roman.append(sym[fsi - 1]);
                    num = r2;
                } else {
                    for (int i = 0; i < d; i++) {
                        roman.append(sym[fsi]);
                    }
                    num = r;
                }
            }
            f = f / s[si];
            si++;
            si %= 2;
            f2 = f2 / s2[si2];
            si2++;
            si2 %= 2;
            fsi++;
        }
        return roman.toString();
    }
    public static void main(String[] args) {
        System.out.println(intToRoman(3));
        System.out.println(intToRoman(4));
        System.out.println(intToRoman(9));
        System.out.println(intToRoman(58));
        System.out.println(intToRoman(1994));
    }
}


输出:

III

IV

IX

LVIII

MCMXCIV

目录
相关文章
CSDN每日一练(Java)--小艺的英文名
CSDN每日一练(Java)--小艺的英文名
|
算法 Java
[Java·算法·简单] LeetCode 13. 罗马数字转整数 详细解读
[Java·算法·简单] LeetCode 13. 罗马数字转整数 详细解读
132 0
|
安全 Java C++
2023-3-25 java选择题每日一练
2023-3-25 java选择题每日一练
91 1
|
C++ Python Rust
Rust 重载运算符|复数结构的“加减乘除”四则运算
Rust 重载运算符|复数结构的“加减乘除”四则运算
223 0
Rust 重载运算符|复数结构的“加减乘除”四则运算
|
Linux
Linux 终端命令之文件浏览(1) cat
Linux 终端命令之文件浏览(1) cat
129 0
Linux 终端命令之文件浏览(1) cat
|
Go Python Rust
Rust 编程小技巧摘选(7)
Rust 编程小技巧摘选(7)
250 0
Rust 编程小技巧摘选(7)
|
Java
LeetCode-整数转罗马数字=Java
整数转罗马数字=Java题解
52 0
|
Java 测试技术
java字符串练习题5、罗马数字转整数
java字符串练习题5、罗马数字转整数
94 0
|
2月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
115 0