PAT——1045. 快速排序

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的N个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?

例如给定N = 5, 排列是1、3、2、4、5。则:

  • 1的左边没有元素,右边的元素都比它大,所以它可能是主元;
  • 尽管3的左边元素都比它小,但是它右边的2它小,所以它不能是主元;
  • 尽管2的右边元素都比它大,但其左边的3比它大,所以它不能是主元;
  • 类似原因,4和5都可能是主元。 

    因此,有3个元素可能是主元。

    输入格式:

    输入在第1行中给出一个正整数N(<= 105); 第2行是空格分隔的N个不同的正整数,每个数不超过109

    输出格式:

    在第1行中输出有可能是主元的元素个数;在第2行中按递增顺序输出这些元素,其间以1个空格分隔,行末不得有多余空格。

    输入样例:
    5
    1 3 2 4 5
    
    输出样例:
    3
    1 4 5

方法1:暴力解决

 1 package com.hone.basical;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 import java.util.Scanner;
 6 /**
 7  * 模拟快速排序,运行时间超时
 8  * 原题目:https://www.patest.cn/contests/pat-b-practise/1044
 9  * @author Xia
10  */
11 public class basicalLevel1045quickSortMain {
12 
13     public static void main(String[] args) {
14         Scanner in = new Scanner(System.in);
15         int n = Integer.parseInt(in.nextLine());
16         int[] a = new int[n];
17         for (int i = 0; i < a.length; i++) {
18             a[i] = in.nextInt();
19         }
20         List<Integer> mainS = new ArrayList<>();
21         for (int i = 0; i < a.length; i++) {
22             int flag = 1;        //1代表是主元
23             //判断左边
24             for (int j = 0; j < i; j++) {
25                 if (a[j]>a[i]) {
26                     flag = 0;
27                     break;
28                 }
29             }
30             for (int j = i+1; j > i&&j<a.length; j++) {
31                 if (a[j]<a[i]) {
32                     flag = 0;
33                     break;
34                 }
35             }
36             if (flag == 1) 
37                 mainS.add(a[i]);
38         }
39         System.out.println(mainS.size());
40         System.out.print(mainS.get(0));
41         for (int i = 1; i < mainS.size(); i++) {
42             System.out.print(" " + mainS.get(i));
43         }
44     }
45 }

方法2:模拟快速排序特征:主元的位置不变

 1 package com.hone.basical;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Arrays;
 5 import java.util.List;
 6 import java.util.Scanner;
 7 /**
 8  * 刚才第一个全部模拟快速排序的方法,时间复杂度太高。(下面定义一个时间复杂度低一些的)
 9  * 原题目:https://www.patest.cn/contests/pat-b-practise/1044
10  * @author Xia
11  * 主元的位置与排完序后该元素所在位置相同,那么再满足它是它之前所有元素中最大的一个,就可以断定它可能是主元。
12  * 此时的时间复杂度为 n 
13  */
14 public class basicalLevel1045quickSortMain2 {
15 
16     public static void main(String[] args) {
17         Scanner in = new Scanner(System.in);
18         int n = Integer.parseInt(in.nextLine());
19         int[] a = new int[n];
20         int[] b = new int[n];        //已经排序的元素
21         int max = 0;                //用于标记使用
22         for (int i = 0; i < a.length; i++) {
23             a[i] = in.nextInt();
24             b[i] = a[i];
25         }
26         Arrays.sort(b);
27         List<Integer> mainS = new ArrayList<>();
28         for (int i = 0; i < n; i++) {
29             if (a[i]>max) 
30                 max = a[i];
31         //如果当前数是从第一个数到当前数最大的一个,且与排完顺序对应位置的数相同则该数就有可能是主元  
32             if (max == b[i]&&a[i] == b[i])
33                 mainS.add(b[i]);
34         }
35         System.out.println(mainS.size());
36         System.out.print(mainS.get(0));
37         for (int i = 1; i < mainS.size(); i++) {
38             System.out.print(" " + mainS.get(i));
39         }
40     }
41 }

原文地址:https://www.cnblogs.com/xiaxj/p/7860321.html