Skip to content
Programmingoneonone
Programmingoneonone
  • Engineering Subjects
    • Internet of Things (IoT)
    • Digital Communication
    • Human Values
  • Programming Tutorials
    • C Programming
    • Data structures and Algorithms
    • 100+ Java Programs
    • 100+ C Programs
    • 100+ C++ Programs
  • Solutions
    • HackerRank
      • Algorithms Solutions
      • C solutions
      • C++ solutions
      • Java solutions
      • Python solutions
      • Data Structures Solutions
    • Leetcode Solutions
    • HackerEarth Solutions
  • Work with US
Programmingoneonone
Programmingoneonone

Hackerrank Determining DNA Health problem solution

YASH PAL, 31 July 202423 January 2026

Hackerrank Determining DNA Health problem solution – DNA is a nucleic acid present in the bodies of living things. Each piece of DNA contains a number of genes, some of which are beneficial and increase the DNA’s total health.

Each gene has a health value, and the total health of a DNA is the sum of the health values of all the beneficial genes that occur as a substring in the DNA. We represent genes and DNA as non-empty strings of lowercase English alphabetic letters, and the same gene may appear multiple times as a susbtring of a DNA.

Given the following:

  • An array of beneficial gene strings.
  • An array of gene health values.
  • A set of  DNA strands where the definition of each strand has three component.

Find and print the respective total healths of the unhealthiest (minimum total health) and healthiest (maximum total health) strands of DNA as two space-separated values on a single line.

Hackerrank Determining DNA Health problem solution

Hackerrank Determining DNA Health problem solution in Python.

from math import inf
from bisect import bisect_left as bLeft, bisect_right as bRight
from collections import defaultdict

def getHealth(seq, first, last, largest):
  h, ls = 0, len(seq)
  for f in range(ls):
    for j in range(1, largest+1):
      if f+j > ls: break
      sub = seq[f:f+j]
      if sub not in subs: break
      if sub not in gMap: continue
      ids, hs = gMap[sub]
      h += hs[bRight(ids, last)]-hs[bLeft(ids, first)]
  return h

howGenes = int(input())
genes = input().rstrip().split()
healths = list(map(int, input().rstrip().split()))
howStrands = int(input())
gMap = defaultdict(lambda: [[], [0]])
subs = set()
for id, gene in enumerate(genes):
  gMap[gene][0].append(id)
  for j in range(1, min(len(gene), 500)+1): subs.add(gene[:j])
for v in gMap.values():
  for i, ix in enumerate(v[0]): v[1].append(v[1][i]+healths[ix])

largest = max(list(map(len, genes)))
hMin, hMax = inf, 0
for _ in range(howStrands):
  firstLastd = input().split()
  first = int(firstLastd[0])
  last = int(firstLastd[1])
  strand = firstLastd[2]
  h = getHealth(strand, first, last, largest)
  hMin, hMax = min(hMin, h), max(hMax, h)
print(hMin, hMax)

Determining DNA Health problem solution in Java.

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Arrays;

public class Solution {

    private static String[] genes;
    private static int[] health;

    public static void main(String[] args) throws Exception {
        PrintStream out = new PrintStream(System.out);
        
        long startMillis = System.currentTimeMillis();
        
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(in.readLine());

        genes = new String[n];
        int longestKey = 0;
        
        String[] genesItems = in.readLine().split(" ");

        Trie trie = new Solution().new Trie();
        for (int i = 0; i < n; i++) {
            String genesItem = genesItems[i];
            genes[i] = genesItem;
            
            trie.insert(genes[i], i);
            
            if (genes[i].length() > longestKey)
                longestKey = genes[i].length();
        }

        health = new int[n];

        String[] healthItems = in.readLine().split(" ");
        
        for (int i = 0; i < n; i++) {
            int healthItem = Integer.parseInt(healthItems[i]);
            health[i] = healthItem;
        }

        //out.println("Longest key: " + longestKey);
        //out.println("Loading: " + (System.currentTimeMillis() - startMillis)/1000f);
        startMillis = System.currentTimeMillis();
        
        int s = Integer.parseInt(in.readLine());
        long maxH = 0, minH = Long.MAX_VALUE;
        
        for (int sItr = 0; sItr < s; sItr++) {
            String[] firstLastd = in.readLine().split(" ");

            int first = Integer.parseInt(firstLastd[0]);
            int last = Integer.parseInt(firstLastd[1]);

            String d = firstLastd[2];
            long total = 0;
            int keyLen = d.length();
            
            for (int i = 0; i < keyLen; i++) {
                total += trie.find(d.substring(i, keyLen > longestKey && i + longestKey < keyLen? i + longestKey : keyLen), first, last);
            }
            
            if (total > maxH)
                maxH = total;
            
            if (total < minH)
                minH = total;
        }
        
        in.close();
        out.println(minH + " " + maxH);
        out.close();
    }
    
    class Trie {
        private final short SIZE = 26;
        private TrieNode root;
        
        public Trie () {
            this.root = new TrieNode();
        }
        
        class TrieNode {
            private TrieNode[] children = new TrieNode[SIZE]; 
            private int index[];
            private boolean isEnd;
            
            public TrieNode(){
                isEnd = false;
            }
            
            @Override
            public String toString(){
                return (index != null? Arrays.toString(index) + " " : "") 
                        + Arrays.toString(Arrays.stream(children).filter(p -> p != null).toArray());
            }
        }
        
        public void insert(String key, int index) {
            int arrayPos;
            
            TrieNode node = root;
            
            for (int i = 0; i < key.length(); i++) {
                arrayPos = key.charAt(i) - 'a';
                
                if (node.children[arrayPos] == null) {
                    node.children[arrayPos] = new TrieNode();
                }
                
                node = node.children[arrayPos];
            }
            
            if (node.index == null) {
                node.index = new int[1];
            } else {
                node.index = Arrays.copyOf(node.index, node.index.length + 1);
            }
            
            node.index[node.index.length - 1] = index;
            node.isEnd = true;
        }
        
        public long find(String key, int start, int end) {
            int arrayPos;
            
            TrieNode node = root;
            long result = 0;
            int keyLen = key.length();
            
            for (int i = 0; i < keyLen; i++) {
                arrayPos = key.charAt(i) - 'a';
                
                if (node.children[arrayPos] != null) {
                    node = node.children[arrayPos];
                    
                    if (node.isEnd 
                            && (   start <= node.index[node.index.length - 1] 
                                || end >= node.index[0])) {
                        
                        int sI = -1, eI = -1;
                        for (int j = 0, k = node.index.length - 1; j < node.index.length && k >= 0; j++, k--) {
                            if (sI == -1) {
                                if (node.index[j] >= start)
                                    sI = j;
                                else if (node.index[k] < start && k + 1 < node.index.length && node.index[k + 1] >= start)
                                    sI = k + 1;
                            }
                            
                            if (eI == -1) {
                                if (node.index[k] <= end)
                                    eI = k;
                                else if (node.index[j] > end && j - 1 >= 0 && node.index[j - 1] <= end)
                                    eI = j - 1;
                            }
                            
                            if (j == k || (sI != -1 && eI != -1))
                                break;
                        }
                        
                        if (sI != -1 && eI != -1) {
                            for (int j = sI; j <= eI; j++) {
                                result += health[node.index[j]];
                            }
                        }
                    }
                } else
                    break;
            }
            
            return result;
        }
        
        @Override
        public String toString() {
            return root.toString();
        }
    }
}

Problem solution in C++ programming.

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdlib>
#include <map>
#include <set>
#include <queue>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;


struct trie 
{
  vector<int> term;
  struct trie* next[26];
  struct trie* fail;
  trie() 
  {
    fail = NULL;
    for (int i=0; i<26; i++)
      next[i] = NULL;
  }
};
trie *root;

void insert(char str[], int index)
{
  trie* p = root;
  int len = strlen(str);
  for (int i=0; i<len; i++)
  {
    int idx = str[i]-'a';
    if (p->next[idx]==NULL)
      p->next[idx] = new trie();
    p = p->next[idx];
  }
  p->term.push_back(index);
}

void buildfail()
{
  queue<trie*> q;
  q.push(root);
  while(!q.empty())
  {
    trie* cur = q.front();
    q.pop();
    for (int i=0; i<26; i++)
    {
      if (cur->next[i] != NULL)
      {
        if (cur == root)
          cur->next[i]->fail = root;
        else
        {
          trie* p = cur->fail;
          while (p!=NULL && p->next[i] == NULL)
            p = p->fail;
          if (p==NULL)
            cur->next[i]->fail = root;
          else
            cur->next[i]->fail = p->next[i];
        }
        q.push(cur->next[i]);
      }
    }
  }
}


vector<pair<vector<int>, int> > query(char str[])
{
  vector<pair<vector<int>, int> > ret;
  int len = strlen(str);
  trie* p = root;
  for (int i=0; i<len; i++)
  {
    int idx = str[i] - 'a';
    while (p->next[idx] == NULL && p!=root)
      p = p->fail;
    if (p->next[idx] == NULL)
      continue;
    p = p->next[idx];
    trie* pp = p;
    while (pp != root)
    {
      if (!pp->term.empty())
        ret.push_back(make_pair(pp->term, i));
      pp = pp->fail;
    }
  }
  return ret;
}

int main()
{
  int n;
  int health[100000];
  char str[2000001];
  scanf("%d", &n);
  root = new trie();
  for (int i=0; i<n; i++)
  {
    scanf("%s", str);
    insert(str, i);
  }
  for (int i=0; i<n; i++)
    scanf("%d", &health[i]);
  buildfail();
  int q;
  scanf("%d", &q);
  long long mins=9999999999999,maxs=0;
  for (int i=0; i<q; i++)
  {
    int a,b;
    scanf("%d %d %s", &a, &b, str);
    vector<pair<vector<int>,int> > ret = query(str);
    long long sum = 0;
    for (int i=0; i<ret.size(); i++)
      for (int j=0; j<ret[i].first.size(); j++)
        if (ret[i].first[j] >= a && ret[i].first[j] <= b)
          sum += health[ret[i].first[j]];
    if (sum > maxs)
      maxs = sum;
    if (sum < mins)
      mins = sum;
  }
  printf("%lld %lldn", mins, maxs);
}

Problem solution in C programming.

#include <assert.h>
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* readline();
char** split_string(char*);

typedef struct TreeNode {
    char ch;
    int* ids;
    int idsLen;
    bool isBlue;
    struct TreeNode* child;
    struct TreeNode* next;
    struct TreeNode* suffix;
    struct TreeNode* blueSuffix;
} TreeNode;

TreeNode* initNode() {
    TreeNode* node = malloc(sizeof(TreeNode));
    node->ch = 0;
    node->ids = NULL;
    node->idsLen = 0;
    node->isBlue = false;
    node->child = NULL;
    node->next = NULL;
    node->suffix = NULL;
    node->blueSuffix = NULL;
    return node;
}

void fillSuffix(TreeNode* root, int size) {
    TreeNode** queue = malloc(size*sizeof(TreeNode*));
    queue[0] = root;
    int head = 0;
    int tail = 1;
    while (head<tail) {
        TreeNode* node = queue[head++];
        TreeNode* child = node->child;
        while (child != NULL) {
            TreeNode* parent_suf = node->suffix;
            bool found_suf = false;
            while (!found_suf && parent_suf != NULL) {
                TreeNode* parent_suf_child = parent_suf->child;
                while (parent_suf_child != NULL && parent_suf_child->ch != child->ch) {
                    parent_suf_child = parent_suf_child->next;
                }
                if (parent_suf_child != NULL) {
                    child->suffix = parent_suf_child;
                    found_suf = true;
                } else {
                    parent_suf = parent_suf->suffix;
                }
            }
            if (!found_suf) child->suffix = root;
            
            queue[tail++] = child;
            child = child->next;
        }
    }
    free(queue);
}

void fillBlueSuffix(TreeNode* root, int size) {
    TreeNode** queue = malloc(size*sizeof(TreeNode*));
    queue[0] = root;
    int head = 0;
    int tail = 1;
    while (head<tail) {
        TreeNode* node = queue[head++];
        TreeNode* child = node->child;
        while (child != NULL) {
            TreeNode* parent_suf = node->suffix;
            bool found_suf = false;
            while (!found_suf && parent_suf != NULL) {
                TreeNode* parent_suf_child = parent_suf->child;
                while (parent_suf_child != NULL && parent_suf_child->ch != child->ch) {
                    parent_suf_child = parent_suf_child->next;
                }
                if (parent_suf_child != NULL && parent_suf_child->isBlue) {
                    child->blueSuffix = parent_suf_child;
                    found_suf = true;
                } else {
                    parent_suf = parent_suf->suffix;
                }
            }
            if (!found_suf) child->blueSuffix = root;
            
            queue[tail++] = child;
            child = child->next;
        }
    }
    free(queue);
}

TreeNode* contructTree(char** genes, int genes_count) {
    TreeNode* root = initNode();
    int size=1;
    for (int i=0; i<genes_count; i++) {
        TreeNode* node = root;
        char* gen = genes[i];
        int len = strlen(gen);
        for (int j=0; j<len; j++) {
            TreeNode* child;
            if (node->child == NULL) {
                child = initNode();
                node->child = child;
                size++;
            } else {
                child = node->child;
                while (child->ch != gen[j] && child->next != NULL) child = child->next;
                if (child->ch != gen[j]) {
                    child->next = initNode();
                    child = child->next;
                    size++;
                }
            }
            node = child;
            node->ch = gen[j];
            if (j==len-1) {
                node->isBlue = true;
                if (node->idsLen == 0) {
                    node->ids = malloc(sizeof(int));
                } else {
                    node->ids = realloc(node->ids, (node->idsLen+1)*sizeof(int));
                }
                node->ids[node->idsLen] = i;
                node->idsLen++;
            }
        }
    }
    fillSuffix(root, size);
    fillBlueSuffix(root, size);
    return root;
}

TreeNode* getChildNode(TreeNode* node, char ch) {
    TreeNode* child = node->child;
    while (child != NULL && child->ch != ch) child = child->next;
    return child;
}

long calHealth(TreeNode* tree, int* health, int first, int last, char* d) {
    long result = 0;
    TreeNode* cur = tree;
    for (int i=0; i<strlen(d); i++) {
        TreeNode* child = getChildNode(cur, d[i]);
        while (child == NULL && cur->suffix != NULL) {
            cur = cur->suffix;
            child = getChildNode(cur, d[i]);
        }
        if (child != NULL) cur = child;
        TreeNode* blue_suffix = cur;
        while (blue_suffix != NULL) {
            for (int i=0; i<blue_suffix->idsLen; i++) {
                if (blue_suffix->ids[i]>=first && blue_suffix->ids[i]<=last) {
                    result += health[blue_suffix->ids[i]];
                }
            }
            blue_suffix = blue_suffix->blueSuffix;
        }
    }
    return result;
}

int main()
{
    char* n_endptr;
    char* n_str = readline();
    int n = strtol(n_str, &n_endptr, 10);
    if (n_endptr == n_str || *n_endptr != '') { exit(EXIT_FAILURE); }

    char** genes_temp = split_string(readline());
    char** genes = malloc(n * sizeof(char*));
    for (int i = 0; i < n; i++) {
        char* genes_item = *(genes_temp + i);
        *(genes + i) = genes_item;
    }
    
    TreeNode* tree = contructTree(genes, n);

    char** health_temp = split_string(readline());
    int* health = malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        char* health_item_endptr;
        char* health_item_str = *(health_temp + i);
        int health_item = strtol(health_item_str, &health_item_endptr, 10);
        if (health_item_endptr == health_item_str || *health_item_endptr != '') { exit(EXIT_FAILURE); }
        *(health + i) = health_item;
    }

    char* s_endptr;
    char* s_str = readline();
    int s = strtol(s_str, &s_endptr, 10);
    if (s_endptr == s_str || *s_endptr != '') { exit(EXIT_FAILURE); }

    long* dna_healths = malloc(s*sizeof(long));

    for (int s_itr = 0; s_itr < s; s_itr++) {
        char** firstLastd = split_string(readline());

        char* first_endptr;
        char* first_str = firstLastd[0];
        int first = strtol(first_str, &first_endptr, 10);
        if (first_endptr == first_str || *first_endptr != '') { exit(EXIT_FAILURE); }

        char* last_endptr;
        char* last_str = firstLastd[1];
        int last = strtol(last_str, &last_endptr, 10);
        if (last_endptr == last_str || *last_endptr != '') { exit(EXIT_FAILURE); }

        char* d = firstLastd[2];
        dna_healths[s_itr] = calHealth(tree, health, first, last, d);
    }
    
    long minHealth = 1000000000000000000;
    long maxHealth = 0;
    for (int i=0; i<s; i++) {
        if (minHealth>dna_healths[i]) minHealth=dna_healths[i];
        if (maxHealth<dna_healths[i]) maxHealth=dna_healths[i];
    }
    printf("%ld %ld", minHealth, maxHealth);

    return 0;
}

char* readline() {
    size_t alloc_length = 1024;
    size_t data_length = 0;
    char* data = malloc(alloc_length);

    while (true) {
        char* cursor = data + data_length;
        char* line = fgets(cursor, alloc_length - data_length, stdin);

        if (!line) { break; }

        data_length += strlen(cursor);

        if (data_length < alloc_length - 1 || data[data_length - 1] == 'n') { break; }

        size_t new_length = alloc_length << 1;
        data = realloc(data, new_length);

        if (!data) { break; }

        alloc_length = new_length;
    }

    if (data[data_length - 1] == 'n') {
        data[data_length - 1] = '';
    }

    data = realloc(data, data_length);

    return data;
}

char** split_string(char* str) {
    char** splits = NULL;
    char* token = strtok(str, " ");

    int spaces = 0;

    while (token) {
        splits = realloc(splits, sizeof(char*) * ++spaces);
        if (!splits) {
            return splits;
        }

        splits[spaces - 1] = token;

        token = strtok(NULL, " ");
    }

    return splits;
}

Problem solution in JavaScript programming.

'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.replace(/s*$/, '')
        .split('n')
        .map(str => str.replace(/s*$/, ''));

    main();
});

function readLine() {
    return inputString[currentLine++];
}

function Node() {
    this.index = [];
    this.indexH = [];
    this.children = {};
}

function Trie() {
    var root = new Node();
    function add(word, node, index, health) {
        var char, previousHealth = 0, len;
        if (word === '') {
            len = node.index.length;
            if (len) {
                previousHealth = node.indexH[len-1];
            }
            node.index.push(index);
            node.indexH.push(health + previousHealth);
            return;
        }
        char = word[0];
        if (!node.children[char]) {
            node.children[char] = new Node();
        }
        add(word.substr(1), node.children[char], index, health);
    }
    return {
        add: function(word, index, health) {
            add(word, root, index, health);
        },
        getRoot: function() {
            return root;
        }
    }
}

function findIndex(arr, start, end, val) {
    var index = Math.floor((end - start) / 2) + start;
    if (arr[index] === val) return index;
    if (arr[start] === val) return start;
    if (arr[end] === val) return end;
    if (arr[index] > val) {
        end = index;
    } else {
        start = index;
    }
    if (end - start <= 1) {
        if (arr[end] < val) {
            return end;
        }
        return start;
    }
    return findIndex(arr, start, end, val);
}

function main() {
    const n = parseInt(readLine(), 10);

    const genes = readLine().split(' ');

    const health = readLine().split(' ').map(healthTemp => parseInt(healthTemp, 10));
    const s = parseInt(readLine(), 10);
    var trie = new Trie();
    var min = null;
    var max = null;

    genes.forEach((gene, index) => {
        trie.add(gene, index, health[index]);
    });
    for (let sItr = 0; sItr < s; sItr++) {
        const firstLastd = readLine().split(' ');

        const first = parseInt(firstLastd[0], 10);

        const last = parseInt(firstLastd[1], 10);

        const d = firstLastd[2];
        var len = d.length;
        var dnaHealth = 0;

        var getSum = function(cn) {
            var cnIndexLen = cn.index.length;
            var startIndex, endIndex;
            if (cnIndexLen === 0) return;
            startIndex = findIndex(cn.index, 0, cnIndexLen - 1, first - 1);
            endIndex = findIndex(cn.index, 0, cnIndexLen - 1, last);
            if (cn.index[endIndex] <= last) {
                dnaHealth += cn.indexH[endIndex];
            }
            if (cn.index[startIndex] < first) {
                dnaHealth -= cn.indexH[startIndex];
            }
        };

        for (let i = 0; i < len; i++) {
            var iter = i;
            var node = trie.getRoot();
            do {
                node = node.children[d[iter++]];
                if (!node) {
                    break;
                }
                getSum(node);
            } while(iter < len);
        }

        min = min === null ? dnaHealth : Math.min(min, dnaHealth);
        max = max === null ? dnaHealth : Math.max(max, dnaHealth);
    }
    console.log(`${min} ${max}`)
}

Algorithms coding problems solutions AlgorithmsHackerRank

Post navigation

Previous post
Next post

Leave a Reply

Your email address will not be published. Required fields are marked *

Programmingoneonone

We at Programmingoneonone, also known as Programming101 is a learning hub of programming and other related stuff. We provide free learning tutorials/articles related to programming and other technical stuff to people who are eager to learn about it.

Pages

  • About US
  • Contact US
  • Privacy Policy

Practice

  • Java
  • C++
  • C

Follow US

  • YouTube
  • LinkedIn
  • Facebook
  • Pinterest
  • Instagram
©2026 Programmingoneonone | WordPress Theme by SuperbThemes