前缀和相关题目
2602 462 453 携程笔试题
This commit is contained in:
parent
bdd083a912
commit
2cfc6687bf
195
src/main/java/cn/whaifree/interview/XieChen/Xie3_13.java
Normal file
195
src/main/java/cn/whaifree/interview/XieChen/Xie3_13.java
Normal file
@ -0,0 +1,195 @@
|
||||
package cn.whaifree.interview.XieChen;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/28 13:27
|
||||
* @注释
|
||||
*/
|
||||
public class Xie3_13 {
|
||||
|
||||
|
||||
static class Problem_1 {
|
||||
|
||||
// 游游拿到了一个字符串,她想重排这个字符串后,使得该字符串包含尽可能多的"you"连续子串。你能帮帮她吗?
|
||||
public static void main(String[] args) {
|
||||
// 可以随意重排序
|
||||
// 输入数据 1
|
||||
// yyoouuuu
|
||||
// 输出数据 1
|
||||
// uyouyouu
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
String s = scanner.next();
|
||||
|
||||
char[] chars = s.toCharArray();
|
||||
|
||||
int[] map = new int[26];
|
||||
|
||||
// 统计次数
|
||||
for (char aChar : chars) {
|
||||
map[aChar - 'a'] += 1;
|
||||
}
|
||||
|
||||
int minLength = Math.min(map['y' - 'a'], Math.min(map['o' - 'a'], map['u' - 'a']));
|
||||
map['y' - 'a'] -= minLength;
|
||||
map['o' - 'a'] -= minLength;
|
||||
map['u' - 'a'] -= minLength;
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < map.length; i++) {
|
||||
for (int j = 0; j < map[i]; j++) {
|
||||
stringBuilder.append((char)('a' + i));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < minLength; i++) {
|
||||
stringBuilder.append("you");
|
||||
}
|
||||
|
||||
System.out.println(stringBuilder.toString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static class Problem_2{
|
||||
|
||||
public static void main1(String[] args) {
|
||||
// 游游拿到了一个数组,她每次操作可以任选一个元素加 1或者减 1。
|
||||
// 游游想知道,将所有元素都变成和ai相等需要操作最少多少次?你需要回答ie[1,n]的结果。
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int n = scanner.nextInt();
|
||||
int[] nums = new int[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
nums[i] = scanner.nextInt();
|
||||
}
|
||||
for (int num : nums) {
|
||||
computeTime(nums, num);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void computeTime(int[] nums, int target) {
|
||||
int res = 0;
|
||||
for (int num : nums) {
|
||||
res += Math.abs(num - target);
|
||||
}
|
||||
System.out.println(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果 要求同时+1 -1
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// 游游拿到了一个数组,她每次操作可以任选一个元素加 1或者减 1。
|
||||
// 游游想知道,将所有元素都变成和ai相等需要操作最少多少次?你需要回答ie[1,n]的结果。
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int n = scanner.nextInt();
|
||||
int[] nums = new int[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
nums[i] = scanner.nextInt();
|
||||
}
|
||||
// 先排序,
|
||||
Arrays.sort(nums);
|
||||
// 对于nums内的元素,遍历target
|
||||
// 左边 部分+1,右边部分-1,直到左边活着右边全部=target时,就能知道次数,检查还有多少个达不到target的
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
change(nums, i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ints
|
||||
* @param index 中间的位置
|
||||
*/
|
||||
public static void change(int[] ints, int index) {
|
||||
// 例如 1 2 3 4 5 选取target 为3
|
||||
|
||||
// 统计左右距离ints[index]的数量
|
||||
int leftSub = 0;
|
||||
for (int i = 0; i < index; i++) {
|
||||
leftSub += ints[index] - ints[i];
|
||||
}
|
||||
int rightSub = 0;
|
||||
for (int i = index + 1; i < ints.length; i++) {
|
||||
rightSub += ints[i] - ints[index];
|
||||
}
|
||||
System.out.println(rightSub + leftSub);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class Problem_3{
|
||||
|
||||
public static void main1(String[] args) {
|
||||
String input = "[1(1),2(2),-3(31),3(2222222222222222),2(12)]";
|
||||
Pattern pattern = Pattern.compile("(-?\\d+)\\((-?\\d+)\\)");
|
||||
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
while (matcher.find()) {
|
||||
String beforeBracket = matcher.group(1);
|
||||
String insideBracket = matcher.group(2);
|
||||
System.out.println("括号前的数字: " + beforeBracket + ", 括号内部的数字: " + insideBracket);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
String s = scanner.next();
|
||||
List<long[]> list = new ArrayList<>();
|
||||
// 正则表达式 获取s
|
||||
// ()左右括号
|
||||
// -?表示可选符号,0或1此-号
|
||||
// \d 为十进制数字
|
||||
// \d+ 表示\d可以出现1次或多次
|
||||
// \\ 为\的转义
|
||||
// \\( 和 \\) 要匹配字面意义上的左括号和右括号
|
||||
Pattern pattern = Pattern.compile("(-?\\d+)\\((-?\\d+)\\)");
|
||||
Matcher matcher = pattern.matcher(s);
|
||||
|
||||
while (matcher.find()) {
|
||||
String beforeBracket = matcher.group(1); // 返回给定组在上一个匹配操作期间捕获的输入子序列。
|
||||
String insideBracket = matcher.group(2);
|
||||
list.add(new long[]{Long.parseLong(beforeBracket),Long.parseLong(insideBracket)});
|
||||
}
|
||||
compact(list);
|
||||
}
|
||||
|
||||
public static void compact(List<long[]> list) {
|
||||
for (int i = 1; i < list.size(); i++) {
|
||||
if (list.get(i)[0] == list.get(i - 1)[0]) {
|
||||
list.set(i, new long[]{i, list.get(i)[1] + list.get(i - 1)[1]});
|
||||
list.remove(i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> res = new ArrayList<>();
|
||||
for (long[] ints : list) {
|
||||
StringBuilder s1 = new StringBuilder();
|
||||
s1.append(ints[0]).append("(").append(ints[1]).append(")");
|
||||
res.add(s1.toString());
|
||||
}
|
||||
System.out.println(res.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Problem_4{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
163
src/main/java/cn/whaifree/interview/XieChen/xc328.java
Normal file
163
src/main/java/cn/whaifree/interview/XieChen/xc328.java
Normal file
@ -0,0 +1,163 @@
|
||||
package cn.whaifree.interview.XieChen;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/28 19:15
|
||||
* @注释
|
||||
*/
|
||||
public class xc328 {
|
||||
|
||||
static class p1{
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int n = scanner.nextInt();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i % 2 == 0) {
|
||||
stringBuilder.append("you");
|
||||
}else {
|
||||
stringBuilder.append("uoy");
|
||||
}
|
||||
}
|
||||
System.out.println(stringBuilder.toString());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class p2{
|
||||
public static void main(String[] args) {
|
||||
Scanner in = new Scanner(System.in);
|
||||
int n = in.nextInt();
|
||||
int m = in.nextInt();
|
||||
int[][] ints = new int[n][m];
|
||||
for (int i = 0; i < n; i++) {
|
||||
String[] split = in.next().split("");
|
||||
for (int j = 0; j < m; j++) {
|
||||
ints[i][j] = Integer.parseInt(split[j]);
|
||||
}
|
||||
}
|
||||
|
||||
// 00 变11
|
||||
// 11 不变
|
||||
// 10 向下走1
|
||||
// 01 变11
|
||||
int res = 0;
|
||||
for (int i = 0; i < ints.length; i++) {
|
||||
for (int j = 0; j < m - 1; j++) {
|
||||
int i1 = ints[i][j];
|
||||
int i2 = ints[i][j + 1];
|
||||
if (i1 == 0 && i2 == 0) {
|
||||
ints[i][j] = 1;
|
||||
ints[i][j + 1] = 1;
|
||||
res++;
|
||||
} else if (i1 == 0 && i2 == 1) {
|
||||
ints[i][j] = 1;
|
||||
res++;
|
||||
} else if (i1 == 1 && i2 == 0 && j == m - 2) {
|
||||
ints[i][j] = 1;
|
||||
res++;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println(res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static class p3{
|
||||
|
||||
public static void t(int[] nums) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 将偶数的区间/2 让整个区间最大
|
||||
public static void main(String[] args) {
|
||||
Scanner in = new Scanner(System.in);
|
||||
int n = in.nextInt();
|
||||
long[] nums = new long[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
nums[i] = in.nextLong();
|
||||
}
|
||||
// 获取前缀和
|
||||
long[] preSum = new long[n + 1];
|
||||
for (int i = 1; i < n + 1; i++) {
|
||||
preSum[i] = preSum[i - 1] + nums[i - 1];
|
||||
}
|
||||
|
||||
|
||||
long nowSum = 0;
|
||||
long minSum = Integer.MAX_VALUE;
|
||||
// 滑动窗口,让窗口内的值都为偶数,并且是总和最小的窗口
|
||||
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
for (int j = i; j < nums.length; j++) {
|
||||
if (Math.abs(nums[j] % 2) == 1) {
|
||||
break;
|
||||
}
|
||||
nowSum += nums[j];
|
||||
minSum = Math.min(nowSum, minSum);
|
||||
}
|
||||
nowSum = 0;
|
||||
}
|
||||
|
||||
// while (right < n) {
|
||||
// if (Math.abs(nums[right] % 2) == 1) {
|
||||
// right++;
|
||||
// left = right;
|
||||
// nowSum = 0;
|
||||
// continue;
|
||||
// }
|
||||
// nowSum += nums[right];
|
||||
// while (nowSum > minSum && left < right) {
|
||||
// nowSum -= nums[left];
|
||||
// left++;
|
||||
// }
|
||||
// minSum = Math.min(nowSum, minSum);
|
||||
// right++;
|
||||
// }
|
||||
|
||||
long sum = 0;
|
||||
for (long num : nums) {
|
||||
sum += num;
|
||||
}
|
||||
System.out.println(sum - minSum / 2);
|
||||
}
|
||||
}
|
||||
|
||||
static class p4{
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int n = scanner.nextInt();
|
||||
int[] ints = new int[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
ints[i] = i;
|
||||
}
|
||||
|
||||
Arrays.sort(ints);
|
||||
// 1 1*2 1*2*3 1*2*3*4
|
||||
|
||||
|
||||
for (int i = 0; i < ints.length; i++) {
|
||||
pro(ints[i],i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 4 6 8
|
||||
public static long pro(long n, long start) {
|
||||
int res = 1;
|
||||
for (long i = start; i < n; i++) {
|
||||
res *= i;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ package cn.whaifree.leetCode.Array;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 209. 长度最小的子数组
|
||||
* 给定一个含有 n 个正整数的数组和一个正整数 target 。
|
||||
@ -82,9 +84,45 @@ public class LeetCode209 {
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 前缀和做法
|
||||
* @param target
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int minSubArrayLen(int target, int[] nums) {
|
||||
// 求前缀和
|
||||
int length = nums.length;
|
||||
int[] preSum = new int[length + 1];
|
||||
for (int i = 1; i < preSum.length; i++) {
|
||||
preSum[i] = preSum[i - 1] + nums[i - 1];
|
||||
}
|
||||
// 2,3,1,2,4,3
|
||||
// 因为每个元素都是正数,所以preSum是递增的,可以用二分查找
|
||||
int minLengthFillSolution = Integer.MAX_VALUE;
|
||||
for (int i = 1; i < preSum.length; i++) {
|
||||
// 从0开始查找
|
||||
int fill = target + preSum[i - 1];
|
||||
int intervalEnd = Arrays.binarySearch(preSum, fill); // 没找到就会返回负数
|
||||
if (intervalEnd < 0) {
|
||||
intervalEnd = -intervalEnd - 1; // 防止查出来的是负数
|
||||
}
|
||||
// 这个区间如果合理,就可能是正常的区间
|
||||
if (intervalEnd <= length)
|
||||
minLengthFillSolution = Math.min(minLengthFillSolution, intervalEnd - (i - 1));
|
||||
// 注意区分下标 intervalEnd和i-1 前缀和为fill和target
|
||||
}
|
||||
return minLengthFillSolution == Integer.MAX_VALUE ? 0 : minLengthFillSolution;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void list() {
|
||||
System.out.println(minSubArrayLen1(5, new int[]{2,3,6}));
|
||||
System.out.println(new Solution().minSubArrayLen(7, new int[]{2, 3, 1, 2, 4, 3}));
|
||||
|
||||
// System.out.println(minSubArrayLen1(5, new int[]{2,3,6}));
|
||||
}
|
||||
|
||||
}
|
||||
|
164
src/main/java/cn/whaifree/leetCode/Array/LeetCode2602.java
Normal file
164
src/main/java/cn/whaifree/leetCode/Array/LeetCode2602.java
Normal file
@ -0,0 +1,164 @@
|
||||
package cn.whaifree.leetCode.Array;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/28 16:59
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode2602 {
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
Solution solution = new Solution();
|
||||
int[] nums = {3,1,6,8};
|
||||
int[] queries = {1,5};
|
||||
List<Long> res = solution.minOperations(nums, queries);
|
||||
res.forEach(System.out::println);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 超时
|
||||
*/
|
||||
class Solution {
|
||||
public List<Long> minOperations(int[] nums, int[] queries) {
|
||||
List<Long> res = new ArrayList<>();
|
||||
for (int query : queries) {
|
||||
res.add(target(nums, query));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public long target(int[] nums, int target) {
|
||||
|
||||
long res = 0;
|
||||
for (int num : nums) {
|
||||
res += Math.abs(target - num);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution1 {
|
||||
public List<Long> minOperations(int[] nums, int[] queries) {
|
||||
List<Long> res = new ArrayList<>();
|
||||
Arrays.sort(nums);
|
||||
// 排序后,找到对应的元素,左边小于,右边大于
|
||||
// 求前缀和
|
||||
int length = nums.length;
|
||||
long[] preSum = new long[length + 1];
|
||||
for (int i = 0; i < length; i++) {
|
||||
preSum[i + 1] = preSum[i] + nums[i];
|
||||
}
|
||||
|
||||
for (int target : queries) {
|
||||
int index = findIndex(nums, target);
|
||||
long left = (long) index * target - preSum[index];
|
||||
// index 为横坐标 target为纵坐标高度 preSum为index位置前面的总和
|
||||
long right = preSum[length] - preSum[index] - (long) target * (length - index);
|
||||
res.add(left + right);
|
||||
}
|
||||
|
||||
// 一侧的前缀和与 “平均值*一侧区间长度” 就代表这一侧的总操作数
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
public int findIndex(int[] nums, int target) {
|
||||
int left = 0;
|
||||
int right = nums.length - 1;
|
||||
while (left <= right) {
|
||||
int mid = left + (right - left) / 2;
|
||||
if (nums[mid] == target) {
|
||||
return mid;
|
||||
} else if (nums[mid] > target) {
|
||||
right = mid - 1;
|
||||
} else {
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
return right;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1()
|
||||
{
|
||||
Solution2 solution2 = new Solution2();
|
||||
int[] nums = {3,1,6,8};
|
||||
int[] queries = {5};
|
||||
List<Long> res = solution2.minOperations(nums, queries);
|
||||
res.forEach(System.out::println);
|
||||
}
|
||||
|
||||
|
||||
class Solution2 {
|
||||
public List<Long> minOperations(int[] nums, int[] queries) {
|
||||
Arrays.sort(nums);
|
||||
|
||||
// 计算前缀和
|
||||
long[] preSum = new long[nums.length + 1];
|
||||
for (int i = 1; i < preSum.length; i++) {
|
||||
preSum[i] = preSum[i - 1] + nums[i - 1];
|
||||
}
|
||||
|
||||
List<Long> res = new ArrayList<>();
|
||||
for (int query : queries) {
|
||||
res.add(getOperation(nums, query, preSum));
|
||||
}
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* <img src="http://42.192.130.83:9000/picgo/imgs/1679808210-FVsAou-t3.png">
|
||||
* </img>
|
||||
* @param nums 原数组
|
||||
* @param target 目标
|
||||
* @param preSum 前缀和
|
||||
* @return
|
||||
*/
|
||||
public Long getOperation(int[] nums, int target,long[] preSum) {
|
||||
|
||||
int index = findIndex(nums, target);
|
||||
// index左边全部比他小、右边全部比他大
|
||||
// 0 - index 为小于他的数字个数 index-length为大于他的个数
|
||||
// 小于他的数的总和 = 小于的个数 index * (target-nums[0]) - index位置的前缀和(前缀和就是一个下三角形的面积)
|
||||
long leftIncr = (long) index * target - preSum[index];
|
||||
long rightIncr =
|
||||
preSum[nums.length] - preSum[index]
|
||||
- (long) target * (nums.length - index);
|
||||
|
||||
return leftIncr + rightIncr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 二分查找
|
||||
* @param nums 有序数组
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public int findIndex(int[] nums, int target) {
|
||||
int left = 0, right = nums.length - 1;
|
||||
while (left <= right) {
|
||||
int mid = (right + left) / 2;
|
||||
if (nums[mid] < target) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid - 1;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
64
src/main/java/cn/whaifree/leetCode/Array/LeetCode453.java
Normal file
64
src/main/java/cn/whaifree/leetCode/Array/LeetCode453.java
Normal file
@ -0,0 +1,64 @@
|
||||
package cn.whaifree.leetCode.Array;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/29 12:54
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode453 {
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
int[] nums = {1, 1,1};
|
||||
int res = new Solution1().minMoves(nums);
|
||||
System.out.println(res);
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* 让n-1个元素加1 等价于让1个元素-1,直到全部元素相等
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int minMoves(int[] nums) {
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (int num : nums) {
|
||||
min = Math.min(min, num);
|
||||
}
|
||||
int res = 0;
|
||||
for (int num : nums) {
|
||||
res += Math.abs(min - num);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution1 {
|
||||
/**
|
||||
* 让n-1个元素加1 等价于让1个元素-1,直到全部元素相等
|
||||
* 前缀和解法
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int minMoves(int[] nums) {
|
||||
|
||||
// 获取前缀和
|
||||
int length = nums.length;
|
||||
int[] preSum = new int[length + 1];
|
||||
// 找到最小的元素的index
|
||||
int minIndex = 0;
|
||||
for (int i = 1; i <= length; i++) {
|
||||
if (nums[minIndex] > nums[i - 1]) {
|
||||
minIndex = i - 1;
|
||||
}
|
||||
preSum[i] = preSum[i - 1] + nums[i - 1];
|
||||
}
|
||||
|
||||
return preSum[length] - nums[minIndex] * length;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
50
src/main/java/cn/whaifree/leetCode/Array/LeetCode462.java
Normal file
50
src/main/java/cn/whaifree/leetCode/Array/LeetCode462.java
Normal file
@ -0,0 +1,50 @@
|
||||
package cn.whaifree.leetCode.Array;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/29 13:15
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode462 {
|
||||
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
Solution solution = new Solution();
|
||||
int[] nums = {1,2,3};
|
||||
int i = solution.minMoves2(nums);
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
class Solution {
|
||||
/**
|
||||
* +1 或 -1
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public int minMoves2(int[] nums) {
|
||||
// 排序后找到中位数
|
||||
Arrays.sort(nums);
|
||||
// 前缀和
|
||||
int length = nums.length;
|
||||
int[] preSum = new int[length + 1];
|
||||
for (int i = 1; i < preSum.length; i++) {
|
||||
preSum[i] = preSum[i - 1] + nums[i - 1];
|
||||
}
|
||||
// 中位数
|
||||
int middleIndex = length / 2;
|
||||
int middleValue = nums[middleIndex];
|
||||
|
||||
int left = middleIndex * middleValue - preSum[middleIndex];
|
||||
int right = preSum[preSum.length - 1] - preSum[middleIndex] - (length - middleIndex) * middleValue;
|
||||
return left + right;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
22
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode139.java
Normal file
22
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode139.java
Normal file
@ -0,0 +1,22 @@
|
||||
package cn.whaifree.leetCode.Dynamic;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/28 13:15
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode139 {
|
||||
|
||||
class Solution {
|
||||
|
||||
// public boolean wordBreak(String s, List<String> wordDict) {
|
||||
// // wordDict放入s的背包
|
||||
// char[] chars = s.toCharArray();
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
}
|
58
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode279.java
Normal file
58
src/main/java/cn/whaifree/leetCode/Dynamic/LeetCode279.java
Normal file
@ -0,0 +1,58 @@
|
||||
package cn.whaifree.leetCode.Dynamic;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/3/28 11:53
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode279 {
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
Solution solution = new Solution();
|
||||
int numSquares = solution.numSquares(12);
|
||||
System.out.println(numSquares);
|
||||
}
|
||||
|
||||
|
||||
class Solution {
|
||||
public int numSquares(int n) {
|
||||
|
||||
// 完全平方数 任意取,使其满足n容量的背包的最少数量
|
||||
// 给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。
|
||||
// dp[j] 表示容量为j的背包 最少 需要的 完全平方数 的数量
|
||||
|
||||
int[] dp = new int[n + 1];
|
||||
Arrays.fill(dp, Integer.MAX_VALUE);
|
||||
|
||||
|
||||
// 求组合数就是外层for循环遍历物品,内层for遍历背包
|
||||
// 求排列数就是外层for遍历背包,内层for循环遍历物品 {1,0} {0,1}
|
||||
// 本题都可以
|
||||
dp[0] = 0;
|
||||
// for (int j = 0; j <= n; j++) {
|
||||
// for (int i = 1; i * i <= j; j++) {
|
||||
// // i-j*j 表示 之前的完全平方数 + 这个挖
|
||||
// dp[j] = Math.min(dp[j - i * i] + 1, dp[j]);
|
||||
// }
|
||||
// }
|
||||
|
||||
for (int i = 1; i * i <= n; i++) {
|
||||
for (int j = i * i; j <= n; j++) {
|
||||
// i-j*j 表示 之前的完全平方数 + 这个挖
|
||||
dp[j] = Math.min(dp[j - i * i] + 1, dp[j]);
|
||||
//dp[j] 可以由dp[j - i * i]推出, dp[j - i * i] + 1 便可以凑成dp[j]。
|
||||
// 或者说, dp[j-i*i]表示j-i*i的最小需要平方数,加上我们给到的i*i这一个平方数,就是+1,即dp[j - i * i] + 1
|
||||
}
|
||||
}
|
||||
|
||||
return dp[n];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user