简体   繁体   中英

I am facing timeout for my solution for a HackerRank

I am solving a problem on hackerrank Hacker Rank ICPC Team Problem

I have created the following code as solution for problem.

import java.math.BigInteger;
import java.util.Scanner;

public class ACMICPCTeam {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt(),m=sc.nextInt(),count=0,maxCount=0,teams=0;
        sc.nextLine();
        String subjectArray[]=new String[n];
        for(int i=0;i<n;i++){
            subjectArray[i]=sc.nextLine();
        }
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                String temp=""+(new BigInteger(subjectArray[i]).add(new BigInteger(subjectArray[j])));
                //System.out.println(temp);
                count=temp.replace("0","").length();
                if(count>maxCount)
                {
                    maxCount=count;
                    teams=1;
                }
                else if(count==maxCount)
                {
                    teams++;
                }
            }
        }
        System.out.println(maxCount);
        System.out.println(teams);
        sc.close();
    }

}

So what I am trying to do is I am adding the two teams subjects and I am counting non-zeros of resultant string. The highest count is number of subjects and the occurrence of highest counts are teams which know max number of subject. Even after spending a lot time I am not able to any better solution than this one still I am facing time out as it is not efficient.

I have gone through forum of the question but it was of no help.

Don't use string logic for this.

Parse the string into aBitSet , before entering your loops, ie as you read them.

Then use methods or(BitSet set) , and cardinality() .

I just completed challenge doing that. No timeouts.

Your solution is not optimal you should try something better.

You can utilize BigInteger method or BitSet class to make it easy.

For forming a team you have to use bitwise OR

Here are solutions--

   // 1st approach
    static int[] acmTeam(String[] topic) {

        int n = topic.length;
        BigInteger[] bi = new BigInteger[n];

        for (int i = 0; i < n; i++)
            bi[i] = new BigInteger(topic[i], 2);

        int maxTopic = 0;
        int teamCount = 0;

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                BigInteger iuj = bi[i].or(bi[j]);
                int bitCount = iuj.bitCount();
                if (bitCount > maxTopic) {
                    maxTopic = bitCount;
                    teamCount = 1;
                } else if (bitCount == maxTopic) {
                    teamCount++;
                }
            }
        }

        int result[] = { maxTopic, teamCount };
        return result;
    }



// 2nd approach--using java BitSet class
    static int[] acmTeamUsingBitSet(String[] topic) {
        int teamCount = 0, maxTopic = 0;
        int size = topic.length;

        BitSet[] bitset = new BitSet[size];
        for (int i = 0; i < size; i++) {
            BigInteger b1 = new BigInteger(topic[i], 2);
            bitset[i] = BitSet.valueOf(b1.toByteArray());
        }
        for (int i = 0; i < size - 1; i++) {
            BitSet bitset1 = bitset[i];
            for (int j = i + 1; j < size; j++) {
                BitSet bitset2 = bitset[j];
                BitSet tmpset = new BitSet();
                tmpset.or(bitset1);
                tmpset.or(bitset2);
                if (tmpset.cardinality() > maxTopic) {
                    maxTopic = tmpset.cardinality();
                    teamCount = 1;
                } else if (maxTopic == tmpset.cardinality()) {
                    teamCount++;
                }
            }

        }
        int result[] = { maxTopic, teamCount };
        return result;

    }

You can refer this link for a detailed video explanation .

I got good result using Java 8.

static int[] acmTeam(String[] topic) {

    List<List<Integer>> res = IntStream.range(0, topic.length)
            .mapToObj(s -> IntStream.range(0, topic[s].length()).boxed()
            .collect(Collectors.groupingBy(i -> topic[s].charAt(i))))
            .map(m -> m.get('1'))
            .collect(toList());
    
    long maxTopic = 0;
    int teamCount = 0;
    
    for (int i = 0; i < res.size(); i++) {
        for (int j = i + 1; j < res.size(); j++) {
            long topics = Stream.concat(res.get(i).stream(), res.get(j).stream()).distinct().count();
            if (topics >  maxTopic) {
                maxTopic = topics;
                teamCount = 1;
            } else if (topics == maxTopic) {
                teamCount++;
            }
        }
    }

    return new int[]{(int) maxTopic, teamCount};
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM