前缀和相关题目
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 org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 209. 长度最小的子数组
|
* 209. 长度最小的子数组
|
||||||
* 给定一个含有 n 个正整数的数组和一个正整数 target 。
|
* 给定一个含有 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
|
@Test
|
||||||
public void list() {
|
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