【HackerRank】Running Time of Quicksort

题目链接:Running Time of Quicksort

Challenge 
In practice, how much faster is Quicksort (in-place) than Insertion Sort? Compare the running time of the two algorithms by counting how many swaps or shifts each one takes to sort an array, and output the difference. You can modify your previous sorting code to keep track of the swaps. The number of swaps required by Quicksort to sort any given input have to be calculated. Keep in mind that the last element of a block is chosen as the pivot, and that the array is sorted in-place as demonstrated in the explanation below.

Any time a number is smaller than the partition, it should be "swapped", even if it doesn‘t actually move to a different location. Also ensure that you count the swap when the pivot is moved into place. The count for Insertion Sort should be the same as the previous challenge, where you just count the number of "shifts".

Input Format 
There will be two lines of input:

  • n - the size of the array
  • ar - n numbers that makes up the array

Output Format 
Output one integer D, where D = (insertion sort shifts) - (quicksort swaps)

Constraints 
1<=s<=1000 
-1000<=x<= 1000 , x ∈ ar

Sample Input

7
1 3 9 8 2 7 5

Sample Output

1

Explanation 
Insertion Sort will take 9 "shifts" to sort the array. Quicksort will take 8 "swaps" to sort it, as shown in the diagram below. 9-8 = 1, the output.



题解:统计排序中快速排序和插入排序元素移动次数的差。对于插入排序,统计元素移动的次数;对于快速排序统计元素交换的次数(包括自己跟自己交换),然后输出二者之差。

对于插入排序元素的移动次数可以参见:Insertion Sort Advanced Analysis,不过这道题暴力可能也可以过,有现成的代码就拿来用了。

对于快速排序,直接在排序过程中统计交换次数就可以了,上述引自HackerRank的图很好的说明了快速排序中Partition的工作过程。

最终代码如下:

  1 import java.util.*;
  2
  3 public class Solution {
  4     private static long answer = 0;
  5     private static long swaps = 0;
  6     private static void swap(int[] ar,int i,int j){
  7         swaps++;
  8         int temp = ar[i];
  9         ar[i] = ar[j];
 10         ar[j]= temp;
 11         return;
 12     }
 13     private static int Partition(int[] ar,int start,int end){
 14         int pivot = ar[end];
 15         int i = start;
 16         int j = start;
 17         while(i<end){
 18             if(ar[i]< pivot ){
 19                 swap(ar,i,j);
 20                 i++;
 21                 j++;
 22             }
 23             else {
 24                 i++;
 25             }
 26         }
 27         swap(ar,j, end);
 28         return j;
 29     }
 30
 31     private static void quickSort(int[] ar,int start,int end){
 32         if(start >= end)
 33             return;
 34         int pivot = Partition(ar,start,end);
 35         quickSort(ar,start,pivot-1);
 36         quickSort(ar, pivot+1, end);
 37     }
 38     private static int[] Merge(int[] ar1,int[] ar2){
 39         int m = ar1.length;
 40         int n = ar2.length;
 41
 42         int point1 = 0;
 43         int point2 = 0;
 44         int index_result = 0;
 45         int[] result = new int[m+n];
 46         while(point1 < m && point2 < n){
 47             if(ar1[point1] < ar2[point2]){
 48                 result[index_result] = ar1[point1];
 49                 point1++;
 50                 index_result++;
 51             }
 52             else if(ar1[point1] > ar2[point2]){
 53                 answer += m - point1;
 54                 result[index_result] = ar2[point2];
 55                 index_result++;
 56                 point2++;
 57             }
 58             else{
 59                 result[index_result] = ar1[point1];
 60                 index_result++;
 61                 point1++;
 62             }
 63         }
 64         while(point1 < m){
 65             result[index_result] = ar1[point1];
 66             index_result++;
 67             point1++;
 68         }
 69         while(point2 < n){
 70             answer += m - point1;
 71             result[index_result] = ar2[point2];
 72             index_result++;
 73             point2++;
 74         }
 75         return result;
 76     }
 77     private static int[] mergeSort(int[] ar){
 78         int n = ar.length;
 79         if(n <= 1)
 80             return ar;
 81         int mid = n/2;
 82         int[] ar1 = new int[mid];
 83         int[] ar2 = new int[n-mid];
 84         System.arraycopy(ar, 0, ar1, 0, mid);
 85         System.arraycopy(ar, mid, ar2, 0, n-mid);
 86         int[] sorted_ar1 = mergeSort(ar1);
 87         int[] sorted_ar2 = mergeSort(ar2);
 88         int[] result = Merge(sorted_ar1, sorted_ar2);
 89         return result;
 90     }
 91     public static void main(String[] args) {
 92
 93         Scanner in = new Scanner(System.in);
 94         int n = in.nextInt();
 95         int[] ar = new int[n];
 96         int[] arr = new int[n];
 97         for(int i = 0;i < n;i++){
 98             ar[i] = in.nextInt();
 99             arr[i]= ar[i];
100         }
101         mergeSort(arr);
102         quickSort(ar, 0, ar.length-1);
103         System.out.println(answer - swaps);
104     }
105 }

【HackerRank】Running Time of Quicksort

时间: 2024-10-08 20:45:35

【HackerRank】Running Time of Quicksort的相关文章

【HackerRank】QuickSort(稳定快排,空间复杂度O(n))

QuickSort In the previous challenge, you wrote a partition method to split an array into 2 sub-arrays, one containing smaller elements and one containing larger elements. This means you 'sorted' half the array with respect to the other half. Can you

【HackerRank】 The Full Counting Sort

In this challenge you need to print the data that accompanies each integer in a list. In addition, if two strings have the same integers, you need to print the strings in their original order. Hence, your sorting algorithm should be stable, i.e. the

【HackerRank】Find the Median(Partition找到数组中位数)

In the Quicksort challenges, you sorted an entire array. Sometimes, you just need specific information about a list of numbers, and doing a full sort would be unnecessary. Can you figure out a way to use your partition code to find the median in an a

【HackerRank】 Sherlock and The Beast

Sherlock and The Beast Sherlock Holmes is getting paranoid about Professor Moriarty, his archenemy. All his efforts to subdue Moriarty have been in vain. These days Sherlock is working on a problem with Dr. Watson. Watson mentioned that the CIA has b

【HackerRank】Median

题目链接:Median 做了整整一天T_T 尝试了各种方法: 首先看了解答,可以用multiset,但是发现java不支持: 然后想起来用堆,这个基本思想其实很巧妙的,就是维护一个最大堆和最小堆,最大堆存放前半部分较小的元素,最小堆存放后半部分较大的元素,并且最大堆的所有元素小于最小堆的所有元素:保持最大堆最多比最小堆多一个元素.每次插入元素的时候都先插入到最大堆,如果发现最大堆比最小堆多了两个个,那么就从最大堆里面拿出最大的放到最小堆里面:如果发现最大堆里面新插入的元素破坏了最大堆所有元素小于

【HackerRank】Game Of Rotation

题目连接:Game Of Rotation Mark is an undergraduate student and he is interested in rotation. A conveyor belt competition is going on in the town which Mark wants to win. In the competition, there's A conveyor belt which can be represented as a strip of 1

【HackerRank】Bus Station

有n组好朋友在公交车站前排队.第i组有ai个人.还有一辆公交车在路线上行驶.公交车的容量大小为x,即它可以同时运载x个人. 当车站来车时(车总是空载过来),一些组从会队头开始走向公交车. 当然,同一组的朋友不想分开,所以仅当公交车能容纳下整个组的时候,他们才会上车.另外,每个人不想失去自己的位置,即组的顺序不会改变. 问题时如何选择公交车的容量大小x使得它可以运走所有组的人,并且公交车每次从车站出发时没有空位?(在车里的总人数恰好达到x)? 输入格式 第一行只包含一个整数n.第二行包含n个空格分

【HackerRank】Sherlock and MiniMax

题目连接:Sherlock and MiniMax Watson gives Sherlock an array A1,A2...AN. He asks him to find an integer M between P and Q(both inclusive), such that, min {|Ai-M|, 1 ≤ i ≤ N} is maximised. If there are multiple solutions, print the smallest one. Input For

【HackerRank】Manasa and Stones

Change language : Manasa 和 她的朋友出去徒步旅行.她发现一条小河里边顺序排列着带有数值的石头.她开始沿河而走,发现相邻两个石头上的数值增加 a 或者 b. 这条小河的尽头有一个宝藏,如果Manasa能够猜出来最后一颗石头上的数值,那么宝藏就是她的.假设第一个石头的上数值为0,找出最后一个石头的可能的所有数值. 输入格式 第一行包含整数 T, 代表测试数据的组数. 每组数组包含三行: 第一行包含 n,代表石头的个数 第二行包含 a 第三行包含 b 输出格式 升序输出最后一