简体   繁体   English

java返回最小的k个元素

[英]java returning the k smallest elements

From an array int[] a , I want to find and return an array with k.length containing the k smallest elements sorted. 我想从数组int[] a中查找并返回一个数组,该数组的k.length包含已排序的k个最小元素。

There cant be any changing of the content of array a. 数组a的内容不能有任何更改。 After making a helping array of k.length I copy the k first values from a, then sorting it. 在创建一个帮助数组k.length之后,我从a复制了k个第一个值,然后对其进行排序。

After this if there is any elements in array a that is smaller than the ones in the help ing array I put it in the right position and the last element disappear and so on. 之后,如果数组a中的任何元素小于帮助数组中的元素,我将其放在正确的位置,最后一个元素消失,依此类推。

Method: 方法:

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

Possible Input: 可能的输入:

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

Output: 输出:

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

Another input: 另一个输入:

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

Output: 输出:

[1, 2, 3]

What I have so far. 到目前为止我所拥有的。 And it's not working and is too inefficient: 而且它不起作用并且效率太低:

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;
}

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

You can sort the array, and get the first k elements from it. 您可以对数组进行排序,并从中获取前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;
}

Hope it helps :) 希望能帮助到你 :)

I guess the below code serves ur purpose, 我猜下面的代码符合您的目的,

public class SortArray { 公共类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]);
    }

}
}

I'd use a Set to discard duplicates and make it a TreeSet so it does all of the sorting itself. 我将使用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]);
}

Here is an implementation which finds K th minimum element in an array containing unique elements. 这是在包含唯一元素的数组中找到第K个最小元素的实现。 If you want to allow duplicates, you can use java.util.Set to eliminate duplicates. 如果要允许重复,则可以使用java.util.Set消除重复。 It is based on randomized Quick Select algorithm and has worst case in order of n . 它基于随机快速选择算法,并且具有n阶的最坏情况。 It outputs unordered sequence of K number of smallest elements from the original array. 它输出原始数组中K个最小元素的无序序列。

First it finds index of Kth smallest elemnt as well as does partial unordered sorting with respect to list[k]. 首先,它找到第K个最小元素的索引,以及对list [k]的部分无序排序。 Therefore, at the end result would contain K numbers which are smaller in the array with the Kth smallest element at the right most position. 因此,最后结果将包含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;
    }
}

I will write this in english, but if you would like an explanation in norwegian, I can do that as well. 我会用英语写,但是如果您想用挪威语解释,我也可以这样做。 I will not write you any code stub, since this is a homework, but try to imagine what you need to get done first: I guess the array a is unsorted, or atleast sorted but in reverse ways as shown in your text? 我不会为您编写任何代码存根,因为这是一项家庭作业,但请尝试想象您首先需要完成的工作:我猜数组a是未排序的,还是至少已排序,但以相反的方式显示,如文本中所示? a cannot be changed. 不能更改。 k, of k length, is supposed to contain the k amount of lowest valued numbers in a. k长度为k的k假定在a中包含k个数量最少的数字。 k must be sorted. k必须排序。

First and foremost, how do you solve problem number 1? 首先,您如何解决问题1? What I would do (This is more inefficient in the beginning, but you wouldn't have to write as much code): Go through array a, starting by saving the first integer in index 0 in k. 我该怎么做(一开始效率较低,但您不必编写太多代码):遍历数组a,首先将第一个整数保存在索引0中的k中。 Let i++ work it's magic, and then call upon a method where you send in the entire array k, and the new integer. 让i ++发挥神奇的作用,然后调用一个方法,您将在其中发送整个数组k和新的整数。 Make it check (with compareTo()-method) whether or not the new int is lower than the integer in every index in k, moving the other numbers one index ahead all the way (remember to check for null-values, orelse: NPE). 使它(使用compareTo()方法)检查​​new int是否小于k中每个索引中的整数,将其他数字一直向前移动一个索引(请记住检查空值,否则:NPE )。 Return this new array. 返回这个新数组。 This will allow you to save the k lowest numbers, sort them and not change a. 这将使您可以保存k个最低的数字,对其进行排序而不更改a。 I think it would solve your entire problem? 我认为这可以解决您的整个问题?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM