java codility training Genomic-range-query

后端 未结 30 2264
悲哀的现实
悲哀的现实 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:40

    The php 100/100 solution:

    function solution($S, $P, $Q) {
        $S      = str_split($S);
        $len    = count($S);
        $lep    = count($P);
        $arr    = array();
        $result = array();
        $clone  = array_fill(0, 4, 0);
        for($i = 0; $i < $len; $i++){
            $arr[$i] = $clone;
            switch($S[$i]){
                case 'A':
                    $arr[$i][0] = 1;
                    break;
                case 'C':
                    $arr[$i][1] = 1;
                    break;
                case 'G':
                    $arr[$i][2] = 1;
                    break;
                default:
                    $arr[$i][3] = 1;
                    break;
            }
        }
        for($i = 1; $i < $len; $i++){
            for($j = 0; $j < 4; $j++){
                $arr[$i][$j] += $arr[$i - 1][$j];
            }
        }
        for($i = 0; $i < $lep; $i++){
            $x = $P[$i];
            $y = $Q[$i];
            for($a = 0; $a < 4; $a++){
                $sub = 0;
                if($x - 1 >= 0){
                    $sub = $arr[$x - 1][$a];
                }
                if($arr[$y][$a] - $sub > 0){
                    $result[$i] = $a + 1;
                    break;
                }
            }
        }
        return $result;
    }
    
    0 讨论(0)
  • 2021-02-01 13:43

    Java 100/100

    class Solution {
    public int[] solution(String S, int[] P, int[] Q) {
        int     qSize       = Q.length;
        int[]   answers     = new int[qSize];
    
        char[]  sequence    = S.toCharArray();
        int[][] occCount    = new int[3][sequence.length+1];
    
        int[] geneImpactMap = new int['G'+1];
        geneImpactMap['A'] = 0;
        geneImpactMap['C'] = 1;
        geneImpactMap['G'] = 2;
    
        if(sequence[0] != 'T') {
            occCount[geneImpactMap[sequence[0]]][0]++;
        }
    
        for(int i = 0; i < sequence.length; i++) {
            occCount[0][i+1] = occCount[0][i];
            occCount[1][i+1] = occCount[1][i];
            occCount[2][i+1] = occCount[2][i];
    
            if(sequence[i] != 'T') {
                occCount[geneImpactMap[sequence[i]]][i+1]++;
            }
        }
    
        for(int j = 0; j < qSize; j++) {
            for(int k = 0; k < 3; k++) {
                if(occCount[k][Q[j]+1] - occCount[k][P[j]] > 0) {
                    answers[j] = k+1;
                    break;
                }
    
                answers[j] = 4;
            }            
        }
    
        return answers;
    }
    } 
    
    0 讨论(0)
  • 2021-02-01 13:48

    Here is my solution Using Segment Tree O(n)+O(log n)+O(M) time

    public class DNAseq {
    
    
    public static void main(String[] args) {
        String S="CAGCCTA";
        int[] P={2, 5, 0};
        int[] Q={4, 5, 6};
        int [] results=solution(S,P,Q);
        System.out.println(results[0]);
    }
    
    static class segmentNode{
        int l;
        int r;
        int min;
        segmentNode left;
        segmentNode right;
    }
    
    
    
    public static segmentNode buildTree(int[] arr,int l,int r){
        if(l==r){
            segmentNode n=new segmentNode();
            n.l=l;
            n.r=r;
            n.min=arr[l];
            return n;
        }
        int mid=l+(r-l)/2;
        segmentNode le=buildTree(arr,l,mid);
        segmentNode re=buildTree(arr,mid+1,r);
        segmentNode root=new segmentNode();
        root.left=le;
        root.right=re;
        root.l=le.l;
        root.r=re.r;
    
        root.min=Math.min(le.min,re.min);
    
        return root;
    }
    
    public static int getMin(segmentNode root,int l,int r){
        if(root.l>r || root.r<l){
            return Integer.MAX_VALUE;
        }
        if(root.l>=l&& root.r<=r) {
            return root.min;
        }
        return Math.min(getMin(root.left,l,r),getMin(root.right,l,r));
    }
    public static int[] solution(String S, int[] P, int[] Q) {
        int[] arr=new int[S.length()];
        for(int i=0;i<S.length();i++){
            switch (S.charAt(i)) {
            case 'A':
                arr[i]=1;
                break;
            case 'C':
                arr[i]=2;
                break;
            case 'G':
                arr[i]=3;
                break;
            case 'T':
                arr[i]=4;
                break;
            default:
                break;
            }
        }
    
        segmentNode root=buildTree(arr,0,S.length()-1);
        int[] result=new int[P.length];
        for(int i=0;i<P.length;i++){
            result[i]=getMin(root,P[i],Q[i]);
        }
        return result;
    } }
    
    0 讨论(0)
  • 2021-02-01 13:48

    /* 100/100 solution C++. Using prefix sums. Firstly converting chars to integer in nuc variable. Then in a bi-dimensional vector we account the occurrence in S of each nucleoside x in it's respective prefix_sum[s][x]. After we just have to find out the lower nucluoside that occurred in each interval K.

    */ . vector solution(string &S, vector &P, vector &Q) {

    int n=S.size();
    int m=P.size();
    vector<vector<int> > prefix_sum(n+1,vector<int>(4,0));
    int nuc;
    
    //prefix occurrence sum
    for (int s=0;s<n; s++) {
        nuc = S.at(s) == 'A' ? 1 : (S.at(s) == 'C' ? 2 : (S.at(s) == 'G' ? 3 : 4) );        
        for (int u=0;u<4;u++) {
            prefix_sum[s+1][u] = prefix_sum[s][u] + ((u+1)==nuc?1:0);
        }
    }
    
    //find minimal impact factor in each interval K
    int lower_impact_factor;
    
    for (int k=0;k<m;k++) {
    
        lower_impact_factor=4;
        for (int u=2;u>=0;u--) {
            if (prefix_sum[Q[k]+1][u] - prefix_sum[P[k]][u] != 0)
                lower_impact_factor = u+1;
        }
        P[k]=lower_impact_factor;
    }
    
    return P;
    

    }

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

    Java, 100/100, but with no cumulative/prefix sums! I stashed the last occurrence index of lower 3 nucelotides in a array "map". Later I check if the last index is between P-Q. If so it returns the nuclotide, if not found, it's the top one (T):

    class Solution {
    
    int[][] lastOccurrencesMap;
    
    public int[] solution(String S, int[] P, int[] Q) {
        int N = S.length();
        int M = P.length;
    
        int[] result = new int[M];
        lastOccurrencesMap = new int[3][N];
        int lastA = -1;
        int lastC = -1;
        int lastG = -1;
    
        for (int i = 0; i < N; i++) {
            char c = S.charAt(i);
    
            if (c == 'A') {
                lastA = i;
            } else if (c == 'C') {
                lastC = i;
            } else if (c == 'G') {
                lastG = i;
            }
    
            lastOccurrencesMap[0][i] = lastA;
            lastOccurrencesMap[1][i] = lastC;
            lastOccurrencesMap[2][i] = lastG;
        }
    
        for (int i = 0; i < M; i++) {
            int startIndex = P[i];
            int endIndex = Q[i];
    
            int minimum = 4;
            for (int n = 0; n < 3; n++) {
                int lastOccurence = getLastNucleotideOccurrence(startIndex, endIndex, n);
                if (lastOccurence != 0) {
                    minimum = n + 1; 
                    break;
                }
            }
    
            result[i] = minimum;
        }
        return result;
    }
    
    int getLastNucleotideOccurrence(int startIndex, int endIndex, int nucleotideIndex) {
        int[] lastOccurrences = lastOccurrencesMap[nucleotideIndex];
        int endValueLastOccurenceIndex = lastOccurrences[endIndex];
        if (endValueLastOccurenceIndex >= startIndex) {
            return nucleotideIndex + 1;
        } else {
            return 0;
        }
    }
    }
    
    0 讨论(0)
  • 2021-02-01 13:49

    I think I'm using dynamic programming. Here is my solution. Little space. Code is mot really clean, just show my idea.

    class Solution {
    public int[] solution(String S, int[] P, int[] Q) {
        int[] preDominator = new int[S.length()];
        int A = -1;
        int C = -1;
        int G = -1;
        int T = -1;
    
        for (int i = 0; i < S.length(); i++) {
            char c = S.charAt(i);
            if (c == 'A') { 
                A = i;
                preDominator[i] = -1;
            } else if (c == 'C') {
                C = i;
                preDominator[i] = A;
            } else if (c == 'G') {
                G = i;
                preDominator[i] = Math.max(A, C);
            } else {
                T = i;
                preDominator[i] = Math.max(Math.max(A, C), G);
            }
        }
    
        int N = preDominator.length;
        int M = Q.length;
        int[] result = new int[M];
        for (int i = 0; i < M; i++) {
            int p = P[i];
            int q = Math.min(N, Q[i]);
            for (int j = q;;) {
                if (preDominator[j] < p) {
                    char c = S.charAt(j);
                    if (c == 'A') {
                        result[i] = 1;
                    } else if (c == 'C') {
                        result[i] = 2;
                    } else if (c == 'G') {
                        result[i] = 3;
                    } else {
                        result[i] = 4;
                    }
                    break;
                }
                j = preDominator[j];
            }
        }
        return result;
    }
    

    }

    0 讨论(0)
提交回复
热议问题