簡體   English   中英

如何在Java中找到數組的最小覆蓋前綴?

[英]How can I find the smallest covering prefix of an array in Java?

找到給定數組的第一個覆蓋前綴。

給出了一個由 N 個整數組成的非空零索引數組 A。 數組 A 的第一個覆蓋前綴是最小的整數 P,使得數組 A 中出現的每個值也依次出現。

例如,A[0]=2, A[1]=2, A[2]=1, A[3]=0, A[4]=1的數組A的第一個覆蓋前綴是3,因為序列A[0], A[1], A[2], A[3] 等於 2, 2, 1, 0 包含數組 A 中出現的所有值。

我的解決方案是

int ps ( int[] A ) 
{
    int largestvalue=0;
    int index=0;   

    for(each element in Array){
        if(A[i]>largestvalue)
        {
            largestvalue=A[i];
            index=i;
        }
    }

    for(each element in Array)
    {
        if(A[i]==index)
            index=i; 
    }   
    return index;
}

但這僅適用於此輸入,這不是通用解決方案。

得到 100% 以下。

public int ps (int[] a)
    {
        var length = a.Length;
        var temp = new HashSet<int>();
        var result = 0;

        for (int i=0; i<length; i++)
        {
            if (!temp.Contains(a[i]))
            {
                temp.Add(a[i]);
                result = i;
            }
        }
        return result;
    }

我會這樣做

int coveringPrefixIndex(final int[] arr) {
    Map<Integer,Integer> indexes = new HashMap<Integer,Integer>();
    // start from the back
    for(int i = arr.length - 1; i >= 0; i--) {
        indexes.put(arr[i],i);
    }
    // now find the highest value in the map
    int highestIndex = 0;
    for(Integer i : indexes.values()) {
        if(highestIndex < i.intValue()) highestIndex = i.intValue();
    }
    return highestIndex;
}

您的問題來自Alpha 2010 Start Challenge of Codility 平台。 這是我的解決方案,得分為100 這個想法很簡單,我跟蹤輸入數組的計數器數組。 向后遍歷輸入數組,遞減相應的計數器,如果該計數器變為零,則表示我們已找到第一個覆蓋前綴。

public static int solution(int[] A) {
    int size = A.length;
    int[] counters = new int[size];

    for (int a : A)
        counters[a]++;

    for (int i = size - 1; i >= 0; i--) {
        if (--counters[A[i]] == 0)
            return i;
    }

    return 0;
}

100p

public static int ps(int[] a) {
    Set<Integer> temp = new HashSet<Integer>();
    int p = 0;
    for (int i = 0; i < a.length; i++) {
        if (temp.add(a[i])) {
            p = i+1;
        }
    }
    return p;
}

這是我在 C# 中的解決方案:

public static int CoveringPrefix(int[] Array1)
    {
        // Step 1. Get length of Array1
        int Array1Length = 0;
        foreach (int i in Array1) Array1Length++;
        // Step 2. Create a second array with the highest value of the first array as its length
        int highestNum = 0;
        for (int i = 0; i < Array1Length; i++)
        {
            if (Array1[i] > highestNum) highestNum = Array1[i];
        }
        highestNum++;   // Make array compatible for our operation
        int[] Array2 = new int[highestNum];
        for (int i = 0; i < highestNum; i++) Array2[i] = 0; // Fill values with zeros
        // Step 3. Final operation will determine unique values in Array1 and return the index of the highest unique value
        int highestIndex = 0;
        for (int i = 0; i < Array1Length; i++)
        {
            if (Array2[Array1[i]] < 1)
            {
                Array2[Array1[i]]++;
                highestIndex = i;
            }
        }
        return highestIndex;
    }

你也可以試試這個解決方案

import java.util.HashSet;
import java.util.Set;

class Solution {
    public int ps ( int[] A ) {
        Set set = new HashSet();
        int index =-1;

        for(int i=0;i<A.length;i++){
            if(set.contains(A[i])){
                if(index==-1)
                    index = i;
            }else{
                index = i;
                set.add(A[i]);
            }         
        }
        return index;
    }
}
    //method must be public for codility to access
public int solution(int A[]){
    Set<Integer> set = new HashSet<Integer>(A.length);
    int index= A[0];
    for (int i = 0; i < A.length; i++) {
        if( set.contains(A[i])) continue;
        index = i;
        set.add(A[i]);
    }   
    return index;
}

這得到了 100%,但是由於 HashSet,檢測到的時間是 O(N * log N)。 你沒有哈希集的解決方案我真的沒有遵循......

java中可能的最短代碼:

    public static int solution(int A[]){
    Set<Integer> set = new HashSet<Integer>(A.length);//avoid resizing
    int index= -1; //value does not matter;
    for (int i = 0; i < A.length; i++) 
        if( !set.contains(A[i])) set.add(A[index = i]); //assignment + eval     
    return index;
}

我得到了 100% 這個:

public int solution (int A[]){
    int index = -1;
    boolean found[] = new boolean[A.length];

    for (int i = 0; i < A.length; i++)
        if (!found [A[i]] ){
            index = i;
            found [A[i]] = true;
        }

    return index;    
}

我使用了一個布爾數組來跟蹤讀取的元素。

這就是我在Java 中所做的,以實現 100% 的正確性和 81% 的性能,使用列表來存儲和比較值。

通過 random_n_log_100000 random_n_10000 或 random_n_100000 測試還不夠快,但它是一個正確答案。

public int solution(int[] A) {
    int N = A.length;
    ArrayList<Integer> temp = new ArrayList<Integer>();

    for(int i=0; i<N; i++){
        if(!temp.contains(A[i])){
            temp.add(A[i]);
        }
    }

    for(int j=0; j<N; j++){
        if(temp.contains(A[j])){
            temp.remove((Object)A[j]);
        }
        if(temp.isEmpty()){
            return j;
        }
    }

    return -1;
}

正確性和性能:100%:

import java.util.HashMap;
class Solution {

   public int solution(int[] inputArray)
   {
      int covering;
      int[] A = inputArray;
      int N = A.length;
      HashMap<Integer, Integer> map = new HashMap<>();
      covering = 0;

      for (int i = 0; i < N; i++)
      {
          if (map.get(A[i]) == null)
          {
              map.put(A[i], A[i]);
              covering = i;
          }
      }
      return covering;
  }
}

這是我從 Codility 到 PrefixSet 的 Objective-C 解決方案。 100% 正確性和性能。

什么可以改變以使其更有效率? (不使用 c 代碼)。

這個怎么運作:

每次遇到數組中的數字時,我都會檢查是否已將其添加到字典中。

如果它在字典中,那么我知道它不是一個新數字,因此與問題無關。 如果它是一個我們還沒有遇到過的新數字,那么我需要將 indexOftheLastPrefix 更新到該數組位置並將其作為鍵添加到字典中。

它只使用了一個 for 循環,所以只需要通過一次。 Objective-c 代碼很安靜,所以想聽聽任何調整以使其更快。 不過,它確實獲得了 100% 的性能。

int solution(NSMutableArray *A)

{

NSUInteger arraySize = [A count];
NSUInteger indexOflastPrefix=0;

NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init];

for (int i=0; i<arraySize; i++)
{
    if ([myDict objectForKey:[[A objectAtIndex:i]stringValue]])
    {

    }
    else
    {
        [myDict setValue:@"YES" forKey:[[A objectAtIndex:i]stringValue]];
        indexOflastPrefix = i;
    }
}

return indexOflastPrefix;

}

int solution(vector &A) { // 用 C++11 (g++ 4.8.2) 編寫代碼

int max = 0, min = -1;

int maxindex =0,minindex = 0;

min = max =A[0];

for(unsigned int i=1;i<A.size();i++)
{

    if(max < A[i] )
    {
      max = A[i];
      maxindex =i;

    } 
     if(min > A[i])
     {
         min =A[i];
         minindex = i;
     }

}

if(maxindex > minindex)
       return maxindex;
else
    return minindex;

}

fwiw:也獲得了 100% 的可編碼性,並且僅使用一個 HashMap 就很容易理解

public static int solution(int[] A) {
    // write your code in Java SE 8

    int firstCoveringPrefix = 0;
    //HashMap stores unique keys
    HashMap hm = new HashMap();

    for(int i = 0; i < A.length; i++){
        if(!hm.containsKey(A[i])){
            hm.put( A[i] , i );
            firstCoveringPrefix = i;
        }
    }
    return  firstCoveringPrefix;
}

我在 JavaScript 中尋找這個答案,但沒有找到,所以我將 Java 答案轉換為 javascript 並得到了 93%

function solution(A) {
  result=0;
  temp = [];
  for(i=0;i<A.length;i++){
    if (!temp.includes(A[i])){
        temp.push(A[i]);
        result=i;
    }
  }
  return result;
}

不使用任何集合:
搜索每個元素第一次出現的索引,
前綴是該索引的最大值。 向后做以盡早完成:

private static int prefix(int[] array) {
    int max = -1;
    int i = array.length - 1;
    while (i > max) {
        for (int j = 0; j <= i; j++) { // include i
            if (array[i] == array[j]) {
                if (j > max) {
                    max = j;
                }
                break;
            }
        }
        i--;
    }
    return max;
}

// TEST

private static void test(int... array) {
    int prefix = prefix(array);
    int[] segment = Arrays.copyOf(array, prefix+1);
    System.out.printf("%s = %d = %s%n", Arrays.toString(array), prefix, Arrays.toString(segment));
}

public static void main(String[] args) {
    test(2, 2, 1, 0, 1);
    test(2, 2, 1, 0, 4);
    test(2, 0, 1, 0, 1, 2);
    test(1, 1, 1);
    test(1, 2, 3);
    test(4);
    test();  // empty array
}

這是我首先嘗試的。 我得到了 24%

public int ps ( int[] A ) {
int n = A.length, i = 0, r = 0,j = 0;

for (i=0;i<n;i++) {
    for (j=0;j<n;j++) {
        if ((long) A[i] == (long) A[j]) {
            r += 1;
        }
        if (r == n) return i;
    }
}
return -1;
}
// you can also use imports, for example:
import java.util.*;

// you can use System.out.println for debugging purposes, e.g.
// System.out.println("this is a debug message");

    class Solution {
        public int solution(int[] A) {
            // write your code in Java SE 8
            Set<Integer> s = new HashSet<Integer>(); 
            int index = 0;
            for (int i = 0; i < A.length; i++) {
                if (!s.contains(A[i])) {
                    s.add(A[i]);
                    index = i;
                }
            }
            return index;
        }
    }

暫無
暫無

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

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