思路:

  1. 首先判断原始排列是否已经是一个连续子段,如果是,则输出YES并且不需要交换位置;
  2. 如果不是连续子段,则遍历整个排列,找到第一个不在正确位置上的数,记为num;
  3. 从num开始向后找连续子段,直到找到长度为k的连续子段或者遍历完整个排列;
  4. 如果找到了长度为k的连续子段,输出YES,并输出交换的位置为num和子段的第一个数;
  5. 如果没有找到长度为k的连续子段,输出NO。

代码实现如下:

import java.util.Scanner;

public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); int[] arr = new int[n]; for (int i = 0; i < n; i++) { arr[i] = sc.nextInt(); } sc.close();

    // 判断是否已经是连续子段
    boolean isConsecutive = true;
    for (int i = 0; i < n; i++) {
        if (arr[i] != i + 1) {
            isConsecutive = false;
            break;
        }
    }
    
    if (isConsecutive) {
        System.out.println("YES");
        System.out.println("0");
    } else {
        // 找到第一个不在正确位置上的数
        int num = 0;
        for (int i = 0; i < n; i++) {
            if (arr[i] != i + 1) {
                num = arr[i];
                break;
            }
        }
        
        // 从num开始找连续子段
        int start = 0;
        int end = 0;
        for (int i = 0; i < n; i++) {
            if (arr[i] == num) {
                start = i;
                end = i + 1;
                while (end < n && arr[end] == arr[end - 1] + 1) {
                    end++;
                }
                break;
            }
        }
        
        // 判断是否找到了长度为k的连续子段
        if (end - start == k) {
            System.out.println("YES");
            System.out.println("1");
            System.out.println((start + 1) + " " + (end + 1));
        } else {
            System.out.println("NO");
        }
    }
}

}

使用Java编程小红有一个长度为n的排列她可以选择两个位置然后交换两个位置的数。她想知道能否通过最多一次交换使得存在一个连续子段是长度为k的排列。排列是指一个长度为len的整数数组数组中包含1到len 的每个数且每个数只出现一次。输入描述一行两个整数nk表示排列长度和连续子段长度。一行n个整数a12an表示排列。1≤k≤n≤105输出描述如果能够通过最多一次交换存在一个连续子段是排列输出 YES并

原文地址: https://www.cveoy.top/t/topic/i6eb 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录