java codility training Genomic-range-query

后端 未结 30 2266
悲哀的现实
悲哀的现实 2021-02-01 12:47

The task is:

A non-empty zero-indexed string S is given. String S consists of N characters from the set of upper-case English letters A, C, G, T.

<
相关标签:
30条回答
  • 2021-02-01 13:30

    Here is the solution, supposing someone is still interested.

    class Solution {
            public int[] solution(String S, int[] P, int[] Q) {
                int[] answer = new int[P.length];
                char[] chars = S.toCharArray();
                int[][] cumulativeAnswers = new int[4][chars.length + 1];
    
                for (int iii = 0; iii < chars.length; iii++) {
                    if (iii > 0) {
                        for (int zzz = 0; zzz < 4; zzz++) {
                            cumulativeAnswers[zzz][iii + 1] = cumulativeAnswers[zzz][iii];
                        }
                    }
    
                    switch (chars[iii]) {
                        case 'A':
                            cumulativeAnswers[0][iii + 1]++;
                            break;
                        case 'C':
                            cumulativeAnswers[1][iii + 1]++;
                            break;
                        case 'G':
                            cumulativeAnswers[2][iii + 1]++;
                            break;
                        case 'T':
                            cumulativeAnswers[3][iii + 1]++;
                            break;
                    }
                }
    
                for (int iii = 0; iii < P.length; iii++) {
                    for (int zzz = 0; zzz < 4; zzz++) {
    
                        if ((cumulativeAnswers[zzz][Q[iii] + 1] - cumulativeAnswers[zzz][P[iii]]) > 0) {
                            answer[iii] = zzz + 1;
                            break;
                        }
    
                    }
                }
    
                return answer;
            }
        }
    
    0 讨论(0)
  • 2021-02-01 13:30

    In case anyone cares about C:

    #include <string.h>
    
    struct Results solution(char *S, int P[], int Q[], int M) {    
        int i, a, b, N, *pA, *pC, *pG;
        struct Results result;
    
        result.A = malloc(sizeof(int) * M);
        result.M = M;
    
        // calculate prefix sums
        N = strlen(S);
        pA = malloc(sizeof(int) * N);
        pC = malloc(sizeof(int) * N);
        pG = malloc(sizeof(int) * N);
        pA[0] = S[0] == 'A' ? 1 : 0;
        pC[0] = S[0] == 'C' ? 1 : 0;
        pG[0] = S[0] == 'G' ? 1 : 0;
        for (i = 1; i < N; i++) {
            pA[i] = pA[i - 1] + (S[i] == 'A' ? 1 : 0);
            pC[i] = pC[i - 1] + (S[i] == 'C' ? 1 : 0);
            pG[i] = pG[i - 1] + (S[i] == 'G' ? 1 : 0);
        }
    
        for (i = 0; i < M; i++) {
            a = P[i] - 1;
            b = Q[i];
    
            if ((pA[b] - pA[a]) > 0) {
                result.A[i] = 1;
            } else if ((pC[b] - pC[a]) > 0) {
                result.A[i] = 2;
            } else if ((pG[b] - pG[a]) > 0) {
                result.A[i] = 3;
            } else {
                result.A[i] = 4;
            }
        }
    
    
        return result;
    }
    
    0 讨论(0)
  • 2021-02-01 13:31
    import java.util.Arrays;
    import java.util.HashMap;
    class Solution {
    
       static HashMap<Character, Integer > characterMapping = new HashMap<Character, Integer>(){{
        put('A',1);
        put('C',2);
        put('G',3);
        put('T',4);
      }};
    
      public static int minimum(int[] arr) {
    
        if (arr.length ==1) return arr[0];
    
        int smallestIndex = 0;
        for (int index = 0; index<arr.length; index++) {
          if (arr[index]<arr[smallestIndex]) smallestIndex=index;
        }
        return arr[smallestIndex];
      }
    
        public int[] solution(String S, int[] P, int[] Q) {
            final char[] characterInput = S.toCharArray();
        final int[] integerInput = new int[characterInput.length];
    
        for(int counter=0; counter < characterInput.length; counter++) {
          integerInput[counter] = characterMapping.get(characterInput[counter]);
        }
    
        int[] result = new int[P.length];
    
        //assuming P and Q have the same length
        for(int index =0; index<P.length; index++) {
    
          if (P[index]==Q[index]) {
            result[index] = integerInput[P[index]];
            break;
          }
          final int[] subArray = Arrays.copyOfRange(integerInput, P[index], Q[index]+1);
          final int minimumValue = minimum(subArray);
          result[index]= minimumValue;
        }
        return result;
        }
    }
    
    0 讨论(0)
  • 2021-02-01 13:31

    Hope this helps.

    public int[] solution(String S, int[] P, int[] K) {
            // write your code in Java SE 8
            char[] sc = S.toCharArray();
            int[] A = new int[sc.length];
            int[] G = new int[sc.length];
            int[] C = new int[sc.length];
    
            int prevA =-1,prevG=-1,prevC=-1;
    
            for(int i=0;i<sc.length;i++){
                if(sc[i]=='A')
                   prevA=i;
                else if(sc[i] == 'G')
                   prevG=i;
                else if(sc[i] =='C')
                   prevC=i;
                A[i] = prevA;
                G[i] = prevG;
                C[i] = prevC;
                //System.out.println(A[i]+ " "+G[i]+" "+C[i]);
    
            }
            int[] result = new int[P.length];
    
            for(int i=0;i<P.length;i++){
                //System.out.println(A[P[i]]+ " "+A[K[i]]+" "+C[P[i]]+" "+C[K[i]]+" "+P[i]+" "+K[i]);
    
                if(A[K[i]] >=P[i] && A[K[i]] <=K[i]){
                      result[i] =1;
                }
                else if(C[K[i]] >=P[i] && C[K[i]] <=K[i]){
                      result[i] =2;
                }else if(G[K[i]] >=P[i] && G[K[i]] <=K[i]){
                      result[i] =3;
                }
                else{
                    result[i]=4;
                }
            }
    
            return result;
        }
    
    0 讨论(0)
  • 2021-02-01 13:32

    Here's my Java (100/100) Solution:

    class Solution {
        private ImpactFactorHolder[] mHolder;
        private static final int A=0,C=1,G=2,T=3;
    
        public int[] solution(String S, int[] P, int[] Q) { 
            mHolder = createImpactHolderArray(S);
    
            int queriesLength = P.length;
            int[] result = new int[queriesLength];
    
            for (int i = 0; i < queriesLength; ++i ) {
                int value = 0;
                if( P[i] == Q[i]) {
                  value = lookupValueForIndex(S.charAt(P[i])) + 1;
                } else {
                 value = calculateMinImpactFactor(P[i], Q[i]);
                }
                result[i] = value;
            }
            return result;    
    
        }
    
        public int calculateMinImpactFactor(int P, int Q) {
            int minImpactFactor = 3;
    
            for (int nucleotide = A; nucleotide <= T; ++nucleotide ) {
                int qValue = mHolder[nucleotide].mOcurrencesSum[Q];
                int pValue = mHolder[nucleotide].mOcurrencesSum[P];
                // handling special cases when the less value is assigned on the P index
                if( P-1 >= 0 ) {
                    pValue = mHolder[nucleotide].mOcurrencesSum[P-1] == 0 ? 0 : pValue;
                } else if ( P == 0 ) {
                    pValue = mHolder[nucleotide].mOcurrencesSum[P] == 1 ? 0 : pValue;
                }
    
                if ( qValue - pValue > 0) {
                    minImpactFactor = nucleotide;
                    break;
                } 
            }        
            return minImpactFactor + 1;
        } 
    
        public int lookupValueForIndex(char nucleotide) {
            int value = 0;
            switch (nucleotide) {
                case 'A' :
                        value = A;
                        break;
                    case 'C' :
                        value = C;
                        break;
                    case 'G':
                       value = G;
                        break;
                    case 'T':
                        value = T;
                        break;
                    default:                    
                        break;
            }
            return value;
        }
    
        public ImpactFactorHolder[] createImpactHolderArray(String S) {
            int length = S.length();
            ImpactFactorHolder[] holder = new ImpactFactorHolder[4];
            holder[A] = new ImpactFactorHolder(1,'A', length);
            holder[C] = new ImpactFactorHolder(2,'C', length);
            holder[G] = new ImpactFactorHolder(3,'G', length);
            holder[T] = new ImpactFactorHolder(4,'T', length);
            int i =0;
            for(char c : S.toCharArray()) {
                int nucleotide = lookupValueForIndex(c);
                ++holder[nucleotide].mAcum;
                holder[nucleotide].mOcurrencesSum[i] = holder[nucleotide].mAcum;  
                holder[A].mOcurrencesSum[i] = holder[A].mAcum;
                holder[C].mOcurrencesSum[i] = holder[C].mAcum;
                holder[G].mOcurrencesSum[i] = holder[G].mAcum;
                holder[T].mOcurrencesSum[i] = holder[T].mAcum;
                ++i;
            }
    
            return holder;
        }
    
        private static class ImpactFactorHolder {
            public ImpactFactorHolder(int impactFactor, char nucleotide, int length) {
                mImpactFactor = impactFactor;
                mNucleotide = nucleotide;
                mOcurrencesSum = new int[length];
                mAcum = 0;
            }
            int mImpactFactor;
            char mNucleotide;
            int[] mOcurrencesSum;
            int mAcum;
        }
    }
    

    Link: https://codility.com/demo/results/demoJFB5EV-EG8/ I'm looking forward to implement a Segment Tree similar to @Abhishek Kumar solution

    0 讨论(0)
  • 2021-02-01 13:33

    Simple, elegant, domain specific, 100/100 solution in JS with comments!

    function solution(S, P, Q) {
        var N = S.length, M = P.length;
    
        // dictionary to map nucleotide to impact factor
        var impact = {A : 1, C : 2, G : 3, T : 4};
    
        // nucleotide total count in DNA
        var currCounter = {A : 0, C : 0, G : 0, T : 0};
    
        // how many times nucleotide repeats at the moment we reach S[i]
        var counters = [];
    
        // result
        var minImpact = [];
    
        var i;
    
        // count nucleotides
        for(i = 0; i <= N; i++) {
            counters.push({A: currCounter.A, C: currCounter.C, G: currCounter.G});
            currCounter[S[i]]++;
        }
    
        // for every query
        for(i = 0; i < M; i++) {
            var from = P[i], to = Q[i] + 1;
    
            // compare count of A at the start of query with count at the end of equry
            // if counter was changed then query contains A
            if(counters[to].A - counters[from].A > 0) {
                minImpact.push(impact.A);
            }
            // same things for C and others nucleotides with higher impact factor
            else if(counters[to].C - counters[from].C > 0) {
                minImpact.push(impact.C);
            }
            else if(counters[to].G - counters[from].G > 0) {
                minImpact.push(impact.G);
            }
            else { // one of the counters MUST be changed, so its T
                minImpact.push(impact.T);
            }
        }
    
        return minImpact;
    }
    
    0 讨论(0)
提交回复
热议问题