专栏导读
本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
给出数字K,请输出所有结果小于K的整数组合到一起的最少交换次数。
组合一起是指满足条件的数字相邻,不要求相邻后在数组中的位置。
数据范围
-100 <=K <= 100
-100 <= 数组中数值 <= 100
二、输入描述
第一行输入数组:1 3 1 4 0
第二行输入K数值:2
三、输出描述
第一行输出最少较好次数:1
备注:
小于2的表达式是 1 1 0,共三种可能将所有符合要求数字组合在一起,最少交换1次
四、解题思路
- 确定滑动窗口大小,滑动窗口的大小取决于有多少个数小于k,假定总共有m个数小于k,这个数值即为滑动窗口的长度;
- 让滑动窗口从数组起始端向右滑动,每滑动一位,就计算出当前窗口内有多少个数小于k,将这些统计数字做比较,找出最大的,假定窗口内最多有n个数小于k;
- m与n的差值就是需要交换的次数。
五、Java算法源码
package com.guor.od;
import java.util.*;
public class OdTest02 {
/**
* 给出数字K,请输出所有结果小于K的整数组合到一起的最少交换次数
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] arr = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int K = sc.nextInt();
// 遍历数组,找出数组里面有多少个数字小于K,确定滑动窗口大小
int target = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] < K) {
target++;
}
}
// 滑动窗口左起点
int left = 0;
// 滑动窗口右终点
int right = target - 1;
// 记录当前窗口范围内有多少个数字小于K
int okSum = 0;
// 再遍历一次,确定初始窗口内有多少个数小于K
for (int i = 0; i <= right; i++) {
if (arr[i] < K) {
okSum++;
}
}
// max用来记录窗口内最多有多少个数小于K
int max = okSum;
// 窗口不停的向右滑动
while (right < arr.length - 1) {
// 左边滑出
if (arr[left++] < K) {
okSum--;
}
// 右边滑入
if (arr[++right] < K) {
okSum++;
}
if (okSum > max) {
max = okSum;
}
}
System.out.println(target - max);
}
}
六、效果展示
1、输入
1 2 3 4 2
3
2、输出
1
3、说明
(1)根据解题思路:
- 确定滑动窗口大小,滑动窗口的大小取决于有多少个数小于k,假定总共有m个数小于k,这个数值即为滑动窗口的长度;
- 让滑动窗口从数组起始端向右滑动,每滑动一位,就计算出当前窗口内有多少个数小于k,将这些统计数字做比较,找出最大的,假定窗口内最多有n个数小于k;
- m与n的差值就是需要交换的次数。
(2)具体解题思路:
- 滑动窗口的大小取决于有多少个数小于k --> m = 3;
- 滑动窗口大小为3,每三个一滑,计算当前窗口内有多少个数小于k;
- 1 2 3 --> 2个
- 2 3 4 --> 1个
- 3 4 2 --> 1个
- 将这些统计数字做比较,找出最大的n=2。
- m与n的差值就是需要交换的次数,即1。
🏆下一篇:华为OD机试 - 荒岛求生 - 栈Stack(Java 2023 B卷 100分)
🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。