【问题标题】:ways to speed up the Full Counting Sort加快全计数排序的方法
【发布时间】:2014-12-04 07:59:20
【问题描述】:

我遇到了关于hackerrank 的问题。 https://www.hackerrank.com/challenges/countingsort4

由于超时,我的第一次尝试通过了除最后一个以外的所有测试用例。 在未能提出更有效的算法后,我使用 StringBuilder 改进了代码,而不是直接连接字符串。这使运行时间从超过 5 秒增加到 3.5 秒。

我的问题是有没有其他方法可以提高运行时间? 谢谢。

以下是我的代码。

public class Solution {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int N = scanner.nextInt();
        scanner.nextLine();

        int[] oriNum = new int[N];        
        String[] oriStr = new String[N];
        int[] count = new int[100];
        int[] indices = new int[100];
        int[] output = new int[N];

        // save the originals and the count array
        for (int i = 0; i < N; i++) {
            oriNum[i] = scanner.nextInt();
            oriStr[i] = scanner.nextLine().trim();
            count[oriNum[i]]++;
        }

        // accumulate the count array
        indices[0] = 0;
        for (int i = 1; i < 100; i++) {
            indices[i] = indices[i-1] + count[i-1];
        }

        // output order
        for (int i = 0; i < N; i++) {
            int num = oriNum[i];
            output[indices[num]++] = i;
        }

        int bar = N/2;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < N; i++) {            
            int index = output[i];
            if (index < bar) 
                sb.append("- ");
            else 
                sb.append(oriStr[index]+ " ");
        }
        System.out.println(sb.toString());
    }
}

【问题讨论】:

  • 代替 sb.append(oriStr[index]+ " ");使用 sb.append(oriStr[index]).append(" ");
  • 这个问题似乎跑题了,因为它要求进行 Code Review,因此属于 Code Review SE。
  • 如果您在搜索如何根据所提到的 HackerRank 问题中的要求使计数排序稳定时偶然登陆该线程,那么请参阅这篇文章 - How is counting sort a stable sort?

标签: java optimization string-concatenation counting-sort


【解决方案1】:

您应该尝试使用普通缓冲阅读器而不是 Scanner。 Scanner 出奇的慢,我参加过的编程比赛中,Scanner 是“超出时间限制”的唯一原因。

【讨论】:

  • 我试用了BufferedReader,运行时间从3.5秒减少到1.4秒。很好的建议,谢谢!
  • 嘿,不客气。我也遇到过这种情况。
【解决方案2】:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution 
{
    public static void main(String[] args)throws Exception 
{
    BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
    int n=Integer.parseInt(in.readLine());
    int[] c=new int[100];
    String[][] dt=new String[100][10300];
    for(int i=0;i<n;i++)
    {
        String[] str=in.readLine().split(" ");
        int val=Integer.parseInt(str[0]);
        if(i<n/2)
            dt[val][c[val]]="-";
        else
             dt[val][c[val]]=str[1];
        c[val]++;
     }
  StringBuilder sb=new StringBuilder("");
    for(int i=0;i<100;i++)
       if(i<n)
        for(int k=0;k<c[i];k++)
            if(dt[i][k]!=null)
               sb.append(dt[i][k]+" ");
            else break;
    System.out.println(sb.toString());
 }
}

【讨论】:

    【解决方案3】:

    这是我解决问题的方法。 (在 C++ 中)。

    void counting_sort(vector<int> &arr, int size,  vector<vector<string> > foo, vector<int> first_half)
    {
        int max = *max_element(arr.begin(), arr.end());
        int min = *min_element(arr.begin(), arr.end());
    
        int range = max - min + 1;
    
        int count[range] = {0};
    
        // counting frequency of numbers in array
        for (int i = 0; i < size; i++)
        {
            count[arr[i] - min]++;
        }
    
        // calculating cumulative sum
        for (int i = 1; i < range; i++)
        {
            count[i] += count[i - 1];
        }
    
        vector<vector<string> > output(size);
    
        // making the new sorted array
        for (int i = size - 1; i >= 0; i--) // traversing from backward for stability
        {
            output[count[arr[i]-min] - 1] = foo[i];
            count[arr[i]-min]--;
        }
    
        // copying the sorted array in original array
        int j=0;
        for (int i = 0; i < size; i++)
        {
            if(stoi(output[i][0]) == first_half[j])
            {
                cout << "- ";
                j++;
            }
            else
            {
                cout << output[i][1] << ' ';
            }
        }
    }
    
    // Complete the countSort function below.
    void countSort(vector<vector<string>> arr) {
    
        vector<int> num;
        vector<int> first_half;
        for(int i=0; (unsigned)i<arr.size(); i++)
        {
            num.push_back(stoi(arr[i][0]));
            if(i < ((unsigned)arr.size()/2))
            {
                first_half.push_back(stoi(arr[i][0]));
            }
        }
    
        sort(first_half.begin(), first_half.end());
        counting_sort(num, num.size(), arr, first_half);
    }
    

    【讨论】:

      猜你喜欢
      • 2012-03-25
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 2011-10-06
      • 2020-06-12
      相关资源
      最近更新 更多