【问题标题】:java returning the k smallest elementsjava返回k个最小元素
【发布时间】:2014-09-12 17:45:08
【问题描述】:

我想从数组int[] a 中找到并返回一个包含已排序的k 个最小元素的k.length 数组。

数组a的内容不能有任何变化。在制作了一个 k.length 的帮助数组后,我从 a 中复制了 k 个第一个值,然后对其进行排序。

在此之后,如果数组 a 中有任何元素小于帮助数组中的元素,我将其放在正确的位置,最后一个元素消失,依此类推。

方法:

public static int[] kMinst(int[] a, int k)

可能的输入:

int[] a = {1,2,3,4,5,6,7,8,9,10}
kMinst(a, a.length);

输出:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

另一个输入:

int[] b = {4,3,2,1}
kMinst(b, 3);

输出:

[1, 2, 3]

到目前为止我所拥有的。而且它不起作用而且效率太低:

public static int[] kMinst(int[] a, int k) {

    if (k < 1 || k > a.length) {
        throw new IllegalArgumentException("k har ikke riktig verdi!");
    }

    int[] verdier = new int[k];

    for (int i = 0; i < verdier.length; i++) {
        verdier[i] = a[i];
    }
    sortering(verdier);

    for (int i = verdier.length; i < a.length; i++) {
        for (int j = verdier.length - 1; j > 0; j --) {
            if (a[i] < a[j]) {
                int temp = a[j];
                for (int l = verdier.length - 1; l > j; l--) {
                    a[l] = a[l - 1];
                }
                a[j] = temp;
            }
        }
    }

    return verdier;
}

【问题讨论】:

  • 我想我已经在几个小时前看到了这个问题。还是只是似曾相识
  • Chu 班的每个人都有相同的作业,TheQuickBrownFox。
  • @B.Dalton 这很正常。但令我惊讶的是,班里的每个人都在 StackOverflow 上发布了作业?
  • @TheQuickBrownFox 哈哈,同意,班长呢?
  • @Toeffen 不,还没有解决。他们删除了问题,并一次又一次地问它:)

标签: java arrays sorting


【解决方案1】:

您可以从原始数据构建一个 O(nlogn) 的堆,然后从该堆中获取 k 个元素,在最坏的情况下也是 O(nlogn)。

【讨论】:

    【解决方案2】:

    您可以对数组进行排序,并从中获取前 k 个元素。

        public static int[] kMinst(int[] a, int k){
        if (k < 1 || k > a.length) {
            throw new IllegalArgumentException("k need to be greater than 1 and lesser than the length of the array");
        }
        int help[] = new int[a.length];
        int res[] = new int[k];
        for(int i = 0; i < a.length; i++) help[i] = a[i]; // copy the a array, not to change it
        Arrays.sort(help);
        for(int i = 0; i < k; i++) res[i] = help[i]; // get the first k elements from the sorted array
        return res;
    }
    

    希望对你有帮助:)

    【讨论】:

      【解决方案3】:

      我猜下面的代码可以满足你的目的,

      公共类 SortArray {

      public int[] sort(int[] a,int b) {
          int c[]=new int[b];
          int temp=0;
       for (int i = 1; i < a.length; i++) {
      
      for (int j = 0; j < i; j++) {
          if(a[i] <=a[j]){
              temp=a[i];
              a[i]=a[j];
              a[j]=temp;      
          }
        }
      }
       for (int i = 0; i < b; i++) {
        c[i]=a[i];    
            }
      return c;
      }
      
      
      public static void main(String[] args) {
          int a[]={7,2,4,5,3,7};
          SortArray sort=new SortArray();
          int[] c=sort.sort(a,3);
          for (int i = 0; i < c.length; i++) {
              System.out.println(c[i]);
          }
      
      }
      }
      

      【讨论】:

        【解决方案4】:

        我会使用Set 丢弃重复项并将其设为TreeSet,以便它自己完成所有排序。

        public static Integer[] kSmallest(Integer[] a, int k) {
            // Use a TreeSet to keep tbhe smallest.
            TreeSet<Integer> kSmallest = new TreeSet<Integer>();
            // Fold all the array into the set.
            for (Integer x : a) {
                // Add it in.
                kSmallest.add(x);
                // Trim to k.
                if (kSmallest.size() > k) {
                    Iterator<Integer> last = kSmallest.descendingIterator();
                    // Select the biggest.
                    last.next();
                    // Remove it.
                    last.remove();
                }
            }
            // Make my result.
            return kSmallest.toArray(new Integer[0]);
        }
        

        【讨论】:

          【解决方案5】:

          这是一个在包含唯一元素的数组中找到第 K 个最小元素的实现。如果要允许重复,可以使用 java.util.Set 来消除重复。 它基于随机快速选择算法,并具有 n 顺序的最坏情况。它输出原始数组中 K 个最小元素的无序序列。

          首先它找到第 K 个最小元素的索引,并针对 list[k] 进行部分无序排序。因此,最终结果将包含 K 个数字,这些数字在数组中较小,第 K 个最小的元素位于最右边。

           public class QuickSelect {
          
              public static void main (String[] args) {
                  final int[] list = new int[]{1,2,11,16,34,3,4,42,5,6,28,7,8,9,10};
                  QuickSelect qs = new QuickSelect();
                  final int k = 10;
                  final int kthMinIndex = qs.findKthMinimum (list, k - 1);
                  System.out.println("[");
                  for (int i = 0; i <= kthMinIndex; i++)
                      System.out.print(list[i] + " ");
                  System.out.print("]");
          
              }
          
              public int findKthMinimum (final int[] list, final int k) {
                  if (k > list.length || k < 1) {
                      throw new IllegalArgumentException("Bad arguments.");
                  }
                  final int left = 0;
                  final int right = list.length - 1;
                  final int pivot = (int)Math.floor((double)left +  (Math.random() * (double)(right - left)));
                  final int result = findKthMinimum (list, left, right, k , pivot);
                  return result;
              }
          
              private int findKthMinimum (final int[] list, int left, int right, final int k, int pivot) {
                  int partitionElement = partition (list, left, right, pivot);
                  while (left != right) {
                      if (partitionElement == k)
                          break;
                      else if (partitionElement > k) {
                          right = partitionElement - 1;
                          pivot = (int)Math.floor((double)left +  (Math.random() * (double)(right - left)));
                      } else if (partitionElement < k) {
                          left = partitionElement + 1;
                          pivot = (int)Math.floor((double)left +  (Math.random() * (double)(right - left)));
                      }
                      partitionElement = partition (list, left, right, pivot);
                  }
                  return list[partitionElement];
              }
          
              private int partition (final int[] list, int left, int right, int pivot) {
                  final int pivotElement = list[pivot];
                  swap (list, pivot, right);
                  int lastStoredIndex = left;
                  for (int i = left; i < right; i++) {
                      if (list[i] < pivotElement) {
                          swap (list, i, lastStoredIndex++);
                      }
                  }
                  swap (list, lastStoredIndex, right);
                  return lastStoredIndex;
              }
          
              private void swap (final int[] list, final int first, final int second) {
                  final int temp = list[first];
                  list[first] = list[second];
                  list[second] = temp;
              }
          }
          

          【讨论】:

            【解决方案6】:

            我会用英语写这个,但如果你想用挪威语解释,我也可以。我不会给你写任何代码存根,因为这是一个家庭作业,但试着想象一下你首先需要完成什么: 我猜数组 a 是未排序的,或者至少是排序的,但在你的文本中显示的方式相反? a 不能更改。 长度为 k 的 k 应该包含 a 中的 k 个最低值数字。 k 必须排序。

            首先,您如何解决第一个问题?我会做什么(这在开始时效率较低,但您不必编写那么多代码): 遍历数组 a,首先将索引 0 中的第一个整数保存在 k 中。让 i++ 发挥它的魔力,然后调用一个发送整个数组 k 和新整数的方法。让它检查(使用 compareTo() 方法)新的 int 是否低于 k 中每个索引中的整数,将其他数字一直向前移动一个索引(记住检查空值,orelse:NPE )。返回这个新数组。 这将允许您保存 k 个最小的数字,对它们进行排序而不更改 a。我认为它会解决你的整个问题?

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-03-03
              • 2019-08-13
              • 2012-10-22
              • 1970-01-01
              • 2015-01-15
              • 2019-04-11
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多