PAT——1045. 快速排序(25)

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的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 package com.hone.basical;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 import java.util.Scanner;
 6 /**
 7  * 模拟快速排序,运行时间超时,按照快速排序的规则模拟,左边的元素都比x小,右边的元素都比x大
 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             //判断右边
31             for (int j = i+1; j > i&&j<a.length; j++) {
32                 if (a[j]<a[i]) {
33                     flag = 0;
34                     break;
35                 }
36             }
37             if (flag == 1) 
38                 mainS.add(a[i]);
39         }
40         System.out.println(mainS.size());
41         System.out.print(mainS.get(0));
42         for (int i = 1; i < mainS.size(); i++) {
43             System.out.print(" " + mainS.get(i));
44         }
45     }
46 }

 

方法二:

 

 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 }

 

posted @ 2017-12-07 09:13  SnailsCoffee  阅读(199)  评论(0编辑  收藏  举报