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. 整数转罗马数字
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
字符 数值
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