簡體   English   中英

找到至少出現 k 次的最小整數

[英]Finding the smallest integer that appears at least k times

給定一個整數數組 A 和一個整數 k。 實現一個算法,在線性時間內確定在 A 中出現至少 k 次的最小整數。

我一直在為這個問題苦苦掙扎,用 Java 編碼,我需要使用 HashTable 來找到出現至少 k 次的最小整數,它也必須在線性時間內。

這是我嘗試過的,但沒有通過任何測試

private static int problem1(int[] arr, int k)
    {
        // Implement me!
    HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
    int ans = Integer.MAX_VALUE;
    for (int i=0; i < arr.length; i++) {
        if(table.containsKey(arr[i])) {
            table.put(arr[i], table.get(arr[i]) + 1);
            if (k <= table.get(arr[i])) {
                ans = Math.min(ans, arr[i]);
            }
        }else{
            table.put(arr[i], 1);
        }
    }

        return ans;
    }

這是包含所有測試用例的空代碼:

import java.io.*;
import java.util.*;

public class Lab5
{

    /**
     *  Problem 1: Find the smallest integer that appears at least k times.
     */
    private static int problem1(int[] arr, int k)
    {
    // Implement me!
       return 0;
    }
    /**
     *  Problem 2: Find two distinct indices i and j such that A[i] = A[j] and |i - j| <= k.
     */
    private static int[] problem2(int[] arr, int k)
    {
        // Implement me!
        int i = -1;
        int j = -1;
        return new int[] { i, j };
    }

    // ---------------------------------------------------------------------
    // Do not change any of the code below!

    private static final int LabNo = 5;
    private static final String quarter = "Fall 2020";
    private static final Random rng = new Random(123456);

    private static boolean testProblem1(int[][] testCase)
    {
        int[] arr = testCase[0];
        int k = testCase[1][0];

        int answer = problem1(arr.clone(), k);

        Arrays.sort(arr);
        for (int i = 0, j = 0; i < arr.length; i = j)
        {
            for (; j < arr.length && arr[i] == arr[j]; j++) { }

            if (j - i >= k)
            {
                return answer == arr[i];
            }
        }

        return false; // Will never happen.
    }

    private static boolean testProblem2(int[][] testCase)
    {
        int[] arr = testCase[0];
        int k = testCase[1][0];

        int[] answer = problem2(arr.clone(), k);

        if (answer == null || answer.length != 2)
        {
            return false;
        }

        Arrays.sort(answer);

        // Check answer
        int i = answer[0];
        int j = answer[1];
        return i != j
            && j - i <= k
            && i >= 0
            && j < arr.length
            && arr[i] == arr[j];
    }

    public static void main(String args[])
    {
        System.out.println("CS 302 -- " + quarter + " -- Lab " + LabNo);
        testProblems(1);
        testProblems(2);
    }

    private static void testProblems(int prob)
    {
        int noOfLines = prob == 1 ? 100000 : 500000;

        System.out.println("-- -- -- -- --");
        System.out.println(noOfLines + " test cases for problem " + prob + ".");

        boolean passedAll = true;

        for (int i = 1; i <= noOfLines; i++)
        {

            int[][] testCase = null;

            boolean passed = false;
            boolean exce = false;

            try
            {
                switch (prob)
                {
                    case 1:
                        testCase = createProblem1(i);
                        passed = testProblem1(testCase);
                        break;

                    case 2:
                        testCase = createProblem2(i);
                        passed = testProblem2(testCase);
                        break;
                }
            }
            catch (Exception ex)
            {
                passed = false;
                exce = true;
            }

            if (!passed)
            {
                System.out.println("Test " + i + " failed!" + (exce ? " (Exception)" : ""));
                passedAll = false;
                break;
            }
        }

        if (passedAll)
        {
            System.out.println("All test passed.");
        }

    }

    private static int[][] createProblem1(int testNo)
    {
        int size = rng.nextInt(Math.min(1000, testNo)) + 5;

        int[] numbers = getRandomNumbers(size, size);
        Arrays.sort(numbers);

        int maxK = 0;

        for (int i = 0, j = 0; i < size; i = j)
        {
            for (; j < size && numbers[i] == numbers[j]; j++) { }
            maxK = Math.max(maxK, j - i);
        }

        int k = rng.nextInt(maxK) + 1;

        shuffle(numbers);

        return new int[][] { numbers, new int[] { k } };
    }

    private static int[][] createProblem2(int testNo)
    {
        int size = rng.nextInt(Math.min(1000, testNo)) + 5;

        int[] numbers = getRandomNumbers(size, size);

        int i = rng.nextInt(size);
        int j = rng.nextInt(size - 1);
        if (i <= j) j++;

        numbers[i] = numbers[j];

        return new int[][] { numbers, new int[] { Math.abs(i - j) } };
    }

    private static void shuffle(int[] arr)
    {
        for (int i = 0; i < arr.length - 1; i++)
        {
            int rndInd = rng.nextInt(arr.length - i) + i;
            int tmp = arr[i];
            arr[i] = arr[rndInd];
            arr[rndInd] = tmp;
        }
    }

    private static int[] getRandomNumbers(int range, int size)
    {
        int numbers[] = new int[size];

        for (int i = 0; i < size; i++)
        {
            numbers[i] = rng.nextInt(2 * range) - range;
        }

        return numbers;
    }
}
private static int problem1(int[] arr, int k) {
        // Implement me!
        Map<Integer, Integer> table = new TreeMap<Integer, Integer>();
        for (int i = 0; i < arr.length; i++) {
            if (table.containsKey(arr[i])) {
                table.put(arr[i], table.get(arr[i]) + 1);
            } else {
                table.put(arr[i], 1);
            }
        }
        for (Map.Entry<Integer,Integer> entry : table.entrySet()) { 
            //As treemap is sorted, we return the first key with value >=k.
            if(entry.getValue()>=k)
                return entry.getKey();
        }
        
        //Not found
        return -1;
    }

正如其他人指出的那樣,有一些錯誤。 首先,您初始化ans的行,

int ans = 0;

您應該將ans初始化為Integer.MAX_VALUE以便當您找到一個首次出現至少k次的整數時, ans被適當地設置為該整數。 其次,在您的 for 循環中,迭代數組時沒有理由跳過第一個元素,因此i應該初始化為0而不是1 此外,在同一行中,您想遍歷整個數組,並且在現在的循環條件中,當k不是數組的長度時,您有i < k 數組的長度由arr.length表示,因此條件應該是i < arr.length 第三,在這一行中,

if (k < table.get(arr[i])){

到目前為止,在遍歷數組時,您試圖檢查一個整數是否在數組中至少出現了k次, <運算符應更改為<=因為這里的關鍵字至少是 k 次,而不是“超過k次”。 第四, k永遠不應該改變,這樣你就可以擺脫這行代碼,

k = table.get(arr[i]);

應用所有這些更改后,您的函數應如下所示:

private static int problem1(int[] arr, int k)
{
    // Implement me!
    HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
    int ans = Integer.MAX_VALUE;
    for (int i=0; i < arr.length; i++) {
        if(table.containsKey(arr[i])) {
            table.put(arr[i], table.get(arr[i]) + 1);
            if (k <= table.get(arr[i])) {
                ans = Math.min(ans, arr[i]);
            }
        }else{
            table.put(arr[i], 1);
        }
    }

    return ans;
}

偽代碼:

  • 收集Map<Integer, Integer>中每個數字的頻率(數字及其計數)
  • 將最小設置為大值
  • 迭代條目
    • 如果條目的值小於k則忽略條目
    • 如果輸入鍵小於當前的最小值,則將其存儲為最小值
  • 回報最少

一行實現:

private static int problem1(int[] arr, int k) {
    return Arrays.stream(arr).boxed()
        .collect(groupingBy(identity(), counting()))
        .entrySet().stream()
        .filter(entry -> entry.getValue() >= k)
        .map(Map.Entry::getKey)
        .reduce(MAX_VALUE, Math::min);
}

這能夠通過所有情況! 感謝所有幫助過的人!!

private static int problem1(int[] arr, int k)
    {
    // Implement me!
        HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
        int ans = Integer.MAX_VALUE;
        for (int i=0; i < arr.length; i++) {
            if(table.containsKey(arr[i])) {
                table.put(arr[i], table.get(arr[i]) + 1);
            }else{
                table.put(arr[i], 1);
            }
        }
         
        Set<Integer> keys = table.keySet();
        
        for(int i : keys){
            if(table.get(i) >= k){
               ans = Math.min(ans,i);
            }
        }
        
        if(ans != Integer.MAX_VALUE){
            return ans;
        }else{
            return 0;
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM