├── _config.yml ├── google35acbac9ba955c0a.html ├── ChocolatesByNumbers.java ├── TieRopes.java ├── AbsDistinct.java ├── CyclicRotation.java ├── FrogJmp.java ├── OddOccurrencesInArray.java ├── MinPerimeterRectangle.java ├── Distinct.java ├── MaxSliceSum.java ├── CountFactors.java ├── ChocolatesByNumbers_SimpleLowPerformance.java ├── Triangle.java ├── MaxProductOfThree.java ├── MaxProfit.java ├── MissingInteger.java ├── PermCheck.java ├── CountDiv.java ├── PassingCars.java ├── BinaryGap.java ├── FrogRiverOne.java ├── StoneWall.java ├── NumberSolitaire.java ├── sitemap.xml ├── MaxNonoverlappingSegments.java ├── PermMissingElem.java ├── CountDistinctSlices_SimpleLowPerformance.java ├── CountTriangles.java ├── Nesting.java ├── CountDistinctSlices.java ├── Brackets.java ├── Dominator.java ├── NumberOfDiscIntersections_SimpleLowPerformance.java ├── Fish.java ├── NumberOfDiscIntersections.java ├── TapeEquilibrium.java ├── MaxDoubleSliceSum.java ├── MinAvgTwoSlice.java ├── Ladder.java ├── CountNonDivisible.java ├── MaxCounters.java ├── Peaks.java ├── MaxSliceSum_Solution_2.java ├── MinMaxDivision.java ├── GenomicRangeQuery.java ├── CountSemiprimes.java ├── FibFrog.java ├── EquiLeader.java └── README.md /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /google35acbac9ba955c0a.html: -------------------------------------------------------------------------------- 1 | google-site-verification: google35acbac9ba955c0a.html -------------------------------------------------------------------------------- /ChocolatesByNumbers.java: -------------------------------------------------------------------------------- 1 | package ChocolatesByNumbers; 2 | 3 | class Solution { 4 | public int solution(int N, int M) { 5 | 6 | // main idea: 7 | // using "gcd(M, N)" 8 | // the number of eaten chocolates = N / gcd(M,N) 9 | return N/(gcd(N,M)); 10 | } 11 | 12 | // using "Euclidean Algorithm" (important) 13 | public static int gcd(int a,int b){ 14 | if(a % b == 0) 15 | return b; // case 1 16 | else 17 | return gcd(b,a % b); // case 2 (key point) 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /TieRopes.java: -------------------------------------------------------------------------------- 1 | package TieRopes; 2 | 3 | class Solution { 4 | public int solution(int K, int[] A) { 5 | 6 | // notice that only "adjacent ropes" can be tied 7 | // so, the problem is simple; we can use "greedy" method 8 | 9 | int total =0; 10 | int currentLength=0; 11 | 12 | for(int i=0; i= K){ 15 | total++; 16 | currentLength=0; // update 17 | } 18 | } 19 | return total; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /AbsDistinct.java: -------------------------------------------------------------------------------- 1 | package AbsDistinct; 2 | 3 | import java.util.*; 4 | 5 | class Solution { 6 | public int solution(int[] A) { 7 | 8 | // using "Set" 9 | Set set = new HashSet<>(); 10 | 11 | for(int i=0; i int) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /OddOccurrencesInArray.java: -------------------------------------------------------------------------------- 1 | package OddOccurrencesInArray; 2 | 3 | class Solution { 4 | public int solution(int[] A) { 5 | // write your code in Java SE 8 6 | 7 | // Using the concept of "XOR" (^) 8 | // when there is a pair A and B 9 | // A^B will be zero 10 | // A^B^C (where C is not paired), 11 | // then A^B^C = C 12 | 13 | // special case 14 | if(A.length == 0) 15 | return 0; 16 | 17 | int unpaired; 18 | unpaired = A[0]; // initial 19 | 20 | for(int i=1; i< A.length; i++){ 21 | unpaired = unpaired ^ A[i]; // xor 22 | } 23 | 24 | return unpaired; // return the unpaired value 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MinPerimeterRectangle.java: -------------------------------------------------------------------------------- 1 | package MinPerimeterRectangle 2 | 3 | class Solution { 4 | public int solution(int N) { 5 | 6 | // main idea: 7 | // try to find the one "closest to sqrt(N)" 8 | 9 | int sqrtN = (int) Math.sqrt(N); 10 | int perimeter = (1 * 2) + (N * 2); // perimeter = (A*2)+(B*2) 11 | 12 | for(int i = sqrtN; i > 0; i--){ // from the one closest to sqrt(N) 13 | if( N % i ==0){ // key point: "N % i ==0" 14 | int A = i; 15 | int B = N/i; 16 | perimeter = (A * 2) + (B * 2); 17 | break; // be careful: break from the for-loop 18 | } 19 | } 20 | 21 | return perimeter; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Distinct.java: -------------------------------------------------------------------------------- 1 | package Distinct; 2 | 3 | // note: remember to import (for using "Arrays.sort(xxx[])") 4 | import java.util.*; 5 | 6 | // System.out.println("this is a debug message"); 7 | 8 | class Solution { 9 | public int solution(int[] A) { 10 | 11 | // special case 12 | if(A.length ==0) 13 | return 0; 14 | 15 | // initial setting: one distinct number 16 | int result =1; 17 | 18 | // Using "Arrays.sort(A)" (important) 19 | Arrays.sort(A); 20 | 21 | // for counting the distinct numbers 22 | for(int i=1; i < A.length; i++){ 23 | if(A[i] != A[i-1]){ // distinct 24 | result++; 25 | } 26 | } 27 | 28 | return result; // return the number of distinct values 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /MaxSliceSum.java: -------------------------------------------------------------------------------- 1 | package MaxSliceSum; 2 | 3 | // much elegant solution 4 | // not using "Math.max( 0, maxEndingHere + A[i])" 5 | // Instead, using "Math.max( A[i], maxEndingPrevious + A[i] )" 6 | 7 | class Solution { 8 | public int solution(int[] A) { 9 | 10 | // initial setting A[0] 11 | int maxEndingPrevious = A[0]; 12 | int maxEndingHere = A[0]; 13 | int maxSoFar = A[0]; 14 | 15 | // note: for i=0, it will return A[0] (also for "one element" cases) 16 | 17 | for(int i = 1; i < A.length; i++){ 18 | maxEndingHere = Math.max(A[i], maxEndingPrevious + A[i]); // <--- key point~!! 19 | maxEndingPrevious = maxEndingHere; 20 | maxSoFar = Math.max(maxSoFar, maxEndingHere); // update the max (be careful) 21 | } 22 | 23 | return maxSoFar; // can be used for "all negative" cases 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /CountFactors.java: -------------------------------------------------------------------------------- 1 | package CountFactors; 2 | 3 | class Solution { 4 | public int solution(int N) { 5 | 6 | // main idea: 7 | // check from 1 to "sqrt_of_N" 8 | // then, taking its pair into consideration 9 | // ---> numFactor = numFactor * 2; 10 | 11 | int sqrtN = (int) Math.sqrt(N); 12 | int numFactor =0; // number of factors 13 | 14 | // check if i is a factor or not (by using N % i ==0) 15 | for(int i=1; i <= sqrtN; i++){ 16 | if(N % i ==0){ 17 | numFactor++; 18 | } 19 | } 20 | 21 | numFactor = numFactor * 2; // add its pair 22 | 23 | // be careful: check if "sqrtN * sqrtN == N" 24 | if( sqrtN * sqrtN == N){ 25 | numFactor = numFactor -1; // minus one: avoid double counting 26 | } 27 | 28 | return numFactor; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ChocolatesByNumbers_SimpleLowPerformance.java: -------------------------------------------------------------------------------- 1 | // This solution is simple and correct 2 | // but a bit low performance (100% correct and 25% performance) 3 | 4 | package ChocolatesByNumbers; 5 | 6 | import java.util.*; 7 | 8 | class Solution { 9 | public int solution(int N, int M) { 10 | 11 | Set set = new HashSet<>(); 12 | 13 | int currentNumber =0; 14 | set.add(currentNumber); // the 1st chocolate 15 | int numChocolate = 1; // eat the 1st one 16 | 17 | while(true){ 18 | currentNumber = (currentNumber + M) % N; 19 | if(set.contains(currentNumber) == true){ 20 | break; 21 | } 22 | else{ 23 | numChocolate++; // eat one more chocolate 24 | set.add(currentNumber); // record its number 25 | } 26 | } 27 | 28 | return numChocolate; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Triangle.java: -------------------------------------------------------------------------------- 1 | package Triangle; 2 | 3 | // note: need to import (so, we can use "Arrays.sort(int[])") 4 | import java.util.*; 5 | 6 | // System.out.println("this is a debug message"); 7 | 8 | class Solution { 9 | public int solution(int[] A) { 10 | 11 | // main idea: for any combination (A[i-2], A[i-1], A[i]) 12 | // we just need to check if A[i-2] + A[i-1] > A[i] (important) 13 | // note: A[i-2] + A[i-1] is the max possible combination (needed to check) 14 | 15 | // Using "Arrays.sort(int[])" 16 | Arrays.sort(A); 17 | 18 | // note: start from i=2 19 | for(int i=2; i< A.length; i++){ 20 | if((long)A[i-2] + (long)A[i-1] > (long)A[i]) // note: using "long" for overflow cases 21 | return 1; 22 | // note: we just need one combination 23 | } 24 | 25 | // otherwise, return 0 (no triangular) 26 | return 0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MaxProductOfThree.java: -------------------------------------------------------------------------------- 1 | package MaxProductOfThree; 2 | 3 | // note: need to import (for using "Arrays.sort(int[])") 4 | import java.util.*; 5 | 6 | // you can write to stdout for debugging purposes, e.g. 7 | // System.out.println("this is a debug message"); 8 | 9 | class Solution { 10 | public int solution(int[] A) { 11 | 12 | // main idea: 13 | // max_1 = positive * positive * positive 14 | // max_2 = negative * negative * positive 15 | // max = Math.max(max_1, max_1) 16 | // just need to sort the integer array 17 | 18 | // sort the array 19 | Arrays.sort(A); 20 | 21 | // max_1 = 1st biggest * 2nd biggest * 3rd biggest 22 | int max_1 = A[A.length-1] * A[A.length-2] * A[A.length-3]; 23 | 24 | // max_2 = 1st smallest * 2nd smallest * 1st biggest 25 | int max_2 = A[0] * A[1] * A[A.length-1]; 26 | 27 | // take the maximum 28 | int max = Math.max(max_1, max_2); 29 | 30 | return max; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MaxProfit.java: -------------------------------------------------------------------------------- 1 | package MaxProfit; 2 | 3 | class Solution { 4 | public int solution(int[] A) { 5 | // main idea (One Pass Solution): 6 | // We can maintain two variables 7 | // 1) minprice (key point~!!) 8 | // 2) maxprofit (corresponding to the smallest valley) 9 | 10 | // special case 11 | if(A.length <= 1) 12 | return 0; // no profit 13 | 14 | // two variables (and initial setting) 15 | int minPrice = A[0]; 16 | int maxProfit =0; 17 | 18 | // one pass solution 19 | for(int i=1; i maxProfit) // update max profit 25 | maxProfit = curProfit; 26 | } 27 | } 28 | 29 | return maxProfit; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /MissingInteger.java: -------------------------------------------------------------------------------- 1 | package MissingInteger; 2 | 3 | import java.util.*; 4 | 5 | class Solution { 6 | public int solution(int[] A) { 7 | // write your code in Java SE 8 8 | 9 | //special case 10 | if(A.length ==0){ 11 | return 1; 12 | } 13 | 14 | // Using "set" to check if an element has appeared 15 | // note: need to "import java.util.*" (important) 16 | Set set = new HashSet(); 17 | 18 | // add elements into the set 19 | for(int i=0; i< A.length; i++){ 20 | set.add(A[i]); 21 | } 22 | 23 | // note: the missing number is not possible bigger than (A.length) 24 | // because there are only (A.length) numbers 25 | for(int i=1; i<= A.length; i++){ 26 | if(set.contains(i) != true) // the 1st missing element 27 | return i; 28 | } 29 | 30 | // means: there are no missing numbers from 1 to A.length 31 | // Therefore, the missing number is "A.length+1" (important) 32 | return A.length+1; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /PermCheck.java: -------------------------------------------------------------------------------- 1 | package PermCheck; 2 | 3 | import java.util.*; 4 | // note: remember to import (when using some data structures) 5 | 6 | class Solution { 7 | public int solution(int[] A) { 8 | // write your code in Java SE 8 9 | 10 | // to check "permutation" 11 | // the main idea is as follows: 12 | // 1. use set to remember which elements have appeared 13 | // 2. use "for loop" to check if all the elements from "1 to A.length" appeared 14 | // If all the elements have appeared, then "yes". 15 | // Otherwise, "no". 16 | 17 | Set set = new HashSet(); 18 | 19 | for(int i=0; i < A.length; i++){ 20 | set.add(A[i]); 21 | } 22 | 23 | // check if "all" the elements from "1 to A.length" appeared 24 | for(int i=1; i<= A.length; i++){ 25 | if( set.contains(i) == false ) 26 | return 0; // not a permutation (A[i] is missing) 27 | } 28 | 29 | // if it contains all the elements (from "1 to A.length") 30 | // then, "yes" 31 | return 1; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /CountDiv.java: -------------------------------------------------------------------------------- 1 | package CountDiv; 2 | 3 | class Solution { 4 | public int solution(int A, int B, int K) { 5 | // write your code in Java SE 8 6 | 7 | // need to achieve low complexity O(1) 8 | // using math equation (low complexity) 9 | 10 | // number of divisible values smaller than B 11 | int num_B = (int) Math.floor( B/K ); 12 | // note: take "Math.floor" which is the basic number 13 | 14 | // number of divisible values smaller than A 15 | int num_A = (int) Math.floor( A/K ); 16 | // note: take "Math.floor" which is the basic number 17 | 18 | // number of divisible numbers 19 | int num_div = num_B - num_A; 20 | 21 | // note: plus one (if A % K == 0) 22 | // because "A" is also divisble 23 | // without "plus", "A" will be deducted 24 | int plus = 0; 25 | if(A % K == 0) 26 | plus = 1; 27 | 28 | // num_div + plus 29 | num_div = num_div + plus; 30 | 31 | // return the number of K-divisible values between A and B 32 | return num_div; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /PassingCars.java: -------------------------------------------------------------------------------- 1 | package PassingCars; 2 | 3 | class Solution { 4 | public int solution(int[] A) { 5 | // write your code in Java SE 8 6 | 7 | // note: find number of pairs (P, Q) 8 | // where P < Q (important) 9 | // try to use "one pass" solution (low time complexity) 10 | 11 | int num_east = 0; // initial 12 | int num_pass = 0; // initial 13 | 14 | for(int i=0; i 1_000_000_000 || num_pass < 0) 30 | return -1; 31 | else 32 | return num_pass; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /BinaryGap.java: -------------------------------------------------------------------------------- 1 | package BinaryGap; 2 | 3 | class Solution { 4 | public int solution(int N) { 5 | // write your code in Java SE 8 6 | 7 | int max_gap = 0; 8 | int current_gap =0; 9 | boolean counting = false; 10 | 11 | // Using the "concept of bit manipulation" and "& operation" 12 | 13 | while( N !=0 ){ 14 | 15 | if(counting == false){ // for the first "1" 16 | if( (N&1) == 1){ // note: cannot use n&1 withoug "()" 17 | counting = true; // start to count 18 | } 19 | } 20 | else{ // counting = true 21 | if( (N&1) ==0){ // note: cannot use n&1 withoug "()" 22 | current_gap ++; 23 | } 24 | else{ // N & 1 == 1 25 | max_gap = Math.max(max_gap, current_gap); 26 | current_gap = 0; // reset 27 | } 28 | } 29 | 30 | N = N >> 1; // shift by one (right side) 31 | // note: cannot just write "N >> 1" 32 | } 33 | 34 | return max_gap; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /FrogRiverOne.java: -------------------------------------------------------------------------------- 1 | package FrogRiverOne; 2 | 3 | import java.util.*; 4 | 5 | class Solution { 6 | public int solution(int X, int[] A) { 7 | // write your code in Java SE 8 8 | 9 | // the main ideas: 10 | // 1. create a "set", and put "1~X" into the set first. 11 | // 2. when a number matches a number in the set, 12 | // then remove the number from the set. 13 | // 3. when the set becomes "empty", 14 | // all the numbers "1~X" have appeared 15 | 16 | Set set = new HashSet(); 17 | 18 | // put "1~X" into the set first 19 | for(int i=1; i<= X; i++){ 20 | set.add(i); 21 | } 22 | 23 | for(int i=0; i< A.length; i++){ 24 | if( set.contains(A[i]) == true ){ // when a number appears, 25 | set.remove(A[i]); // then, remove it from the set 26 | } 27 | if(set.isEmpty() == true){ // nothing in the set 28 | return i; // In second i, "1~X" have all appeared 29 | } 30 | } 31 | 32 | // not all the elements "1~X" appeared 33 | return -1; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /StoneWall.java: -------------------------------------------------------------------------------- 1 | package StoneWall; 2 | 3 | import java.util.*; 4 | 5 | class Solution { 6 | public int solution(int[] H) { 7 | 8 | // main idea: need to use "stack" to check when we need a new block 9 | 10 | Stack st = new Stack<>(); 11 | int numBlock =0; 12 | 13 | // note: H[i] is the ith height of the wall 14 | for(int i=0; i< H.length; i++){ 15 | 16 | // step 1: "stack is not empty" AND "from high to low" 17 | // then, "pop" (it is the key point, be careful) 18 | while( st.isEmpty()==false && st.peek() > H[i] ){ 19 | st.pop(); 20 | } 21 | // step 2: if the stack is empty 22 | if( st.isEmpty() ){ 23 | numBlock++; // add a block 24 | st.push(H[i]); // push the height 25 | } 26 | // step 3: the height is the same: do nothing 27 | else if( st.peek() == H[i] ){ 28 | } 29 | // step 4: from low to high 30 | else if( st.peek() < H[i] ){ 31 | numBlock++; // add a block 32 | st.push(H[i]); // push the height 33 | } 34 | } 35 | 36 | return numBlock; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /NumberSolitaire.java: -------------------------------------------------------------------------------- 1 | package NumberSolitaire; 2 | 3 | class Solution { 4 | public int solution(int[] A) { 5 | 6 | // main idea: 7 | // using "dynamic programming" to build up the solution 8 | // (bottom up) 9 | 10 | int[] dp = new int[A.length]; 11 | dp[0] = A[0]; 12 | 13 | // build up from "dp[1], dp[2], ..., dp[A.length-1]" 14 | for(int i=1; i= 0){ 23 | // very important: not "A[i-die]+A[i]" 24 | // instead, have to use "dp[i-die]+A[i]" 25 | max = Math.max( dp[i-die]+A[i], max ); 26 | // dynamic programming: 27 | // take the best: 28 | // takeBest( dp[i-j] + value[j], curBest ) 29 | } 30 | } 31 | dp[i] = max; // keep the best one as the dp value 32 | } 33 | 34 | return dp[A.length-1]; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | https://mickey0521.github.io/Codility/ 12 | 2019-05-04T15:45:29+00:00 13 | 1.00 14 | 15 | 16 | https://mickey0521.github.io/ 17 | 2019-05-04T15:45:29+00:00 18 | 0.80 19 | 20 | 21 | https://mickey0521.github.io/Deep-Learning-Examples-Jupyter-Notebook/ 22 | 2019-05-04T15:45:29+00:00 23 | 0.80 24 | 25 | 26 | https://mickey0521.github.io/Examples-of-Deep-Learning-Python/ 27 | 2019-05-04T15:45:29+00:00 28 | 0.80 29 | 30 | 31 | https://mickey0521.github.io/LeetCode/ 32 | 2019-05-04T15:45:29+00:00 33 | 0.80 34 | 35 | 36 | -------------------------------------------------------------------------------- /MaxNonoverlappingSegments.java: -------------------------------------------------------------------------------- 1 | package MaxNonoverlappingSegments; 2 | 3 | class Solution { 4 | public int solution(int[] A, int[] B) { 5 | 6 | // main idea: 7 | // Using "greedy" method to find non-overlapping segments 8 | 9 | // because the segments are sorted by their rightEnds 10 | // we use "for loop" from rightEnd to left 11 | // and just need to keep the "value of leftEnd" (key point) 12 | 13 | // spcial case 14 | if(A.length==0) 15 | return 0; 16 | 17 | int N = A.length; 18 | // keep the value of leftEnd: A[i] 19 | // the 1st segment: A[N-1] 20 | int currentLeftEnd = A[N-1]; 21 | int numNonOverlap =1; 22 | 23 | for(int i=N-2; i >=0; i--){ 24 | // if "rightEnd < leftEnd", nonOverlap++ 25 | // and update the value of leftEnd 26 | if(B[i] < currentLeftEnd){ 27 | numNonOverlap++; 28 | currentLeftEnd = A[i]; 29 | } 30 | // if "leftnEnd is shorter", 31 | // update the value of leftEnd (important) 32 | if(A[i] > currentLeftEnd){ 33 | currentLeftEnd = A[i]; 34 | } 35 | } 36 | 37 | return numNonOverlap; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /PermMissingElem.java: -------------------------------------------------------------------------------- 1 | package PermMissingElem; 2 | 3 | class Solution { 4 | public int solution(int[] A) { 5 | // write your code in Java SE 8 6 | 7 | // Using the concept of "Sum = (ceiling + floor) * height /2" 8 | // So---> Sum = (1 + N+1) * N /2 9 | // the missing element can be found by minus other elements 10 | 11 | // note: need to use "long" to avoid potential bugs (large numbers) 12 | long ceiling = A.length +1; 13 | long floor = 1; 14 | long height = A.length + 1; // note: need to plus extra "1" 15 | // because there is one element "missing"! 16 | // be careful about this (important) 17 | long sum = (ceiling +floor) * height /2; // main idea 18 | /* 19 | int high = A.length +1; 20 | int low = 1; 21 | int height = A.length + 1; 22 | int sum = (high +low) * height /2; // main idea 23 | */ 24 | long missing_number = sum; // initial setting (sum) 25 | 26 | for(int i=0; iint) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /CountDistinctSlices_SimpleLowPerformance.java: -------------------------------------------------------------------------------- 1 | // This solution is simple and correct, but with low performance (100% correct, 40% performance) 2 | 3 | package CountDistinctSlices; 4 | 5 | import java.util.*; 6 | 7 | class Solution { 8 | public int solution(int M, int[] A) { 9 | 10 | // key point: using "set" for "each leftEnd" 11 | Set set = new HashSet<>(); 12 | 13 | int leftEnd =0; 14 | int rightEnd =0; 15 | int numDistinct =0; 16 | 17 | while(leftEnd < A.length){ 18 | rightEnd = leftEnd; // for each time, rightEnd bigins at leftEnd 19 | while(rightEnd < A.length){ 20 | if( set.contains( A[rightEnd] ) == false){ // distinct cases 21 | numDistinct++; 22 | 23 | if(numDistinct == 1_000_000_000) 24 | return 1_000_000_000; 25 | 26 | set.add(A[rightEnd]); 27 | } 28 | else{ // not distinct cases (then, break~!!) 29 | break; 30 | } 31 | rightEnd++; 32 | } 33 | 34 | set.clear(); // for next leftEnd 35 | leftEnd++; 36 | } 37 | 38 | return numDistinct; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /CountTriangles.java: -------------------------------------------------------------------------------- 1 | package CountTriangles; 2 | 3 | import java.util.*; 4 | 5 | class Solution { 6 | public int solution(int[] A) { 7 | 8 | int numTriangle = 0; 9 | 10 | // important: sort the edges 11 | // so that we just need to check if 12 | // "1st edge + 2nd edge > 3rd edge" 13 | Arrays.sort(A); 14 | 15 | // Using "Caterpillar method" 16 | // so we can have O(n^2), not O(n^3) 17 | for(int i=0; i < A.length-2; i++){ 18 | 19 | // the leftEnd and rightEnd of the "Caterpillar" 20 | int leftEnd = i+1; 21 | int rightEnd = i+2; 22 | 23 | while(leftEnd < A.length-1){ 24 | 25 | // key point of "Caterpillar method" 26 | if(rightEnd < A.length && A[i] + A[leftEnd] > A[rightEnd]){ 27 | rightEnd++; // increase the Caterpillar 28 | } 29 | else{ 30 | // note: need to minus "1" 31 | // because the rightEnd is not included 32 | numTriangle = numTriangle + (rightEnd - leftEnd - 1); 33 | leftEnd++; // decrease the Caterpillar 34 | } 35 | } 36 | } 37 | 38 | return numTriangle; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Nesting.java: -------------------------------------------------------------------------------- 1 | package Nesting; 2 | 3 | // you can also use imports, for example: 4 | import java.util.*; 5 | 6 | class Solution { 7 | public int solution(String S) { 8 | 9 | // special case 1: empty string 10 | if( S.length() ==0) 11 | return 1; 12 | // special case 2: odd length 13 | else if( S.length() % 2 == 1) 14 | return 0; 15 | 16 | // main idea: use "stack" to check 17 | Stack st = new Stack<>(); 18 | 19 | for(int i=0; i return 0 40 | if( !st.isEmpty() ) 41 | return 0; 42 | else 43 | return 1; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /CountDistinctSlices.java: -------------------------------------------------------------------------------- 1 | package CountDistinctSlices; 2 | 3 | class Solution { 4 | public int solution(int M, int[] A) { 5 | 6 | // This solution is more clever, and much faster O(n) 7 | 8 | // main idea: 9 | // use "boolean[]" to record if an integer is already seen 10 | // also use "leftEnd" and "rightEnd" 11 | 12 | boolean[] seen = new boolean[M+1]; // from 0 to M 13 | // Arrays.fill(seen, false); // note: "false" by default 14 | 15 | int leftEnd=0; 16 | int rightEnd=0; 17 | int numSlice =0; 18 | 19 | // key point: move the "leftEnd" and "rightEnd" of a slice 20 | while(leftEnd < A.length && rightEnd < A.length){ 21 | 22 | // case 1: distinct (rightEnd) 23 | if( seen[A[rightEnd]] == false){ 24 | // note: not just +1 25 | // there could be (rightEnd - leftEnd + 1) combinations (be careful) 26 | numSlice = numSlice + (rightEnd - leftEnd + 1); 27 | if(numSlice >= 1_000_000_000) 28 | return 1_000_000_000; 29 | 30 | // increase the slice to right by "1" (important) 31 | seen[A[rightEnd]] = true; 32 | rightEnd++; 33 | } 34 | // case 2: not distinct 35 | else{ 36 | // decrease the slice from left by "1" (important) 37 | // remove A[leftEnd] from "seen" (be careful) 38 | seen[A[leftEnd]] = false; 39 | leftEnd++; 40 | } 41 | } 42 | 43 | return numSlice; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Brackets.java: -------------------------------------------------------------------------------- 1 | package Brackets; 2 | 3 | // you can also use imports, for example: 4 | import java.util.*; 5 | 6 | class Solution { 7 | public int solution(String S) { 8 | 9 | // main idea: use "Stack" (push and pop) 10 | 11 | //special case 12 | if(S.length() == 0) 13 | return 1; 14 | 15 | // new Stack() 16 | Stack stack = new Stack<>(); 17 | 18 | // scan the string (just one pass) 19 | for(int i=0; i< S.length(); i++){ 20 | // note: push "its pair" 21 | if( S.charAt(i) == '(' ){ 22 | stack.push(')'); 23 | } 24 | else if( S.charAt(i) == '[' ){ 25 | stack.push(']'); 26 | } 27 | else if( S.charAt(i) == '{' ){ 28 | stack.push('}'); 29 | } 30 | // pop and check 31 | else if( S.charAt(i) == ')' || S.charAt(i) == ']' || S.charAt(i) == '}'){ 32 | // important: check if the stack is empty or not (be careful) 33 | if(stack.isEmpty() == true){ 34 | return 0; 35 | } 36 | else{ 37 | char temp = stack.pop(); // check if the stack is empty before pop!!! 38 | if(temp != S.charAt(i)){ // not a pair 39 | return 0; 40 | } 41 | } 42 | } 43 | } 44 | // note: check if the stack is empty or not (be careful) 45 | if( !stack.isEmpty() ){ 46 | return 0; 47 | } 48 | else{ 49 | return 1; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Dominator.java: -------------------------------------------------------------------------------- 1 | package Dominator; 2 | 3 | // you can also use imports, for example: 4 | import java.util.*; 5 | 6 | class Solution { 7 | public int solution(int[] A) { 8 | 9 | // Using "hashMap" for counting 10 | Map map = new HashMap<>(); 11 | 12 | // 1. Counting 13 | // map(key, value) ---> map(number, count) 14 | for(int i=0; i max_Count){ 31 | max_Count = cur_Count; // update max count 32 | max_Number = key; 33 | } 34 | } 35 | 36 | // 3. check if there is a "dominator" or not 37 | if( max_Count > (A.length)/2 ){ 38 | // then, max_Number is the "dominator" 39 | } 40 | else{ 41 | return -1; // no dominator 42 | } 43 | 44 | // 4. return "any index" of "the dominator" 45 | for(int i=0; i=lower[j]){ // note: when "equal to", there is also an intersection 31 | intersection++; 32 | } 33 | } 34 | } 35 | 36 | // for the overflow cases 37 | if(intersection > 10_000_000) 38 | return -1; 39 | 40 | return intersection; // number of intersections 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Fish.java: -------------------------------------------------------------------------------- 1 | package Fish; 2 | 3 | // you can also use imports, for example: 4 | import java.util.*; 5 | 6 | class Solution { 7 | public int solution(int[] A, int[] B) { 8 | 9 | // special case: no fish 10 | if(A.length == 0) 11 | return 0; 12 | 13 | // main idea: use "stack" to store the fishes with B[i]==1 14 | // that is, "push" the downstream fishes into "stack" 15 | // note: "push" the Size of the downstream fish 16 | Stack st = new Stack<>(); 17 | int numAlive = A.length; 18 | 19 | for(int i=0; i A[i] ){ 32 | numAlive--; 33 | break; // the upstream fish is eaten (ending) 34 | } 35 | // if the downstream fish is smaller (eat the downstream fish) 36 | else if(st.peek() < A[i]){ 37 | numAlive--; 38 | st.pop(); // the downstream fish is eaten (not ending) 39 | } 40 | } 41 | } 42 | } 43 | 44 | return numAlive; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /NumberOfDiscIntersections.java: -------------------------------------------------------------------------------- 1 | package NumberOfDiscIntersections; 2 | 3 | // note: need to import (to use "Arrays.sort(int[])" ) 4 | import java.util.*; 5 | 6 | // System.out.println("this is a debug message"); 7 | 8 | class Solution { 9 | public int solution(int[] A) { 10 | 11 | // main idea: 12 | // 1. store all the "lower points" and "upper points" of the discs 13 | // 2. count the intersections (if one upper point > one lower point) 14 | 15 | // note: use "long" for big numbers (be careful) 16 | long[] lower = new long[A.length]; 17 | long[] upper = new long[A.length]; 18 | 19 | for(int i=0; i= lower[j]){ 36 | intersection = intersection + j; // add j intersections 37 | intersection = intersection - i; // minus "i" (avoid double count) 38 | j++; 39 | } 40 | } 41 | 42 | // for the overflow cases 43 | if(intersection > 10_000_000) 44 | return -1; 45 | 46 | return intersection; // number of intersections 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /TapeEquilibrium.java: -------------------------------------------------------------------------------- 1 | package TapeEquilibrium; 2 | 3 | class Solution { 4 | public int solution(int[] A) { 5 | // write your code in Java SE 8 6 | 7 | // Using the concept of Sum 8 | // and, (sum of the 2nd part) = Sum - (sum of the 1st part) 9 | // importantly, difference = |(sum of the 2nd part) - (sum of the 1st part)| 10 | 11 | // First, compute the sum (will be used for several times) 12 | int sum =0; // initial 13 | for(int i=0; i< A.length; i++){ 14 | sum = sum + A[i]; 15 | } 16 | 17 | // then, find the minimum difference 18 | int min_diff = Integer.MAX_VALUE; // initial setting: Integer.MAX_VALUE 19 | 20 | int sum_part_one =0; 21 | int sum_part_two =0; 22 | int diff =0; 23 | 24 | // try to compute the above values in "one pass"! 25 | // for the possible partition-point P 26 | for(int p =1; p< A.length; p++){ 27 | /* no need to use the second for loop (important) 28 | for(int j=0; j< p; j++){ // to compute the sum of the 1st part 29 | sum_part_one = sum_part_one + A[j]; 30 | } 31 | */ 32 | sum_part_one = sum_part_one + A[p-1]; // the sum of part one 33 | sum_part_two = sum - sum_part_one; // the sum of part two 34 | diff = sum_part_one - sum_part_two; // the difference 35 | if(diff <0) // absolute value 36 | diff = -diff; // all the values can be computed (one pass) 37 | 38 | min_diff = Math.min(min_diff, diff); // min difference 39 | } 40 | return min_diff; // return the min difference 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MaxDoubleSliceSum.java: -------------------------------------------------------------------------------- 1 | package MaxDoubleSliceSum; 2 | 3 | class Solution { 4 | public int solution(int[] A) { 5 | 6 | // (X, Y, Z) 7 | // 1st slice: A[X+1] + ... + A[Y-1] 8 | // 2nd slice: A[Y+1] + ... + A[Z-1] 9 | // Key Point: 10 | // The array will be split at "Y" 11 | 12 | // main idea: 13 | // if the middle point is "Y", 14 | // find "maxLeft" and "maxRight" 15 | 16 | int maxLeft[] = new int[A.length]; 17 | int maxRight[] = new int[A.length]; 18 | 19 | // 1) find "maxLeft" 20 | // maxLeft[i] is the maximum sum "contiguous subsequence" ending at index i 21 | // note: because it is "contiguous", we only need the ending index (important) 22 | for(int i=1; i< A.length ;i++){ // be careful: from i=1 (because of maxLeft[i-1]) 23 | maxLeft[i] = Math.max(0, maxLeft[i-1]+A[i] ); //golden slice algorithm: Math.max(0, maxLeft[i-1]+A[i] ) 24 | } 25 | 26 | // 2) find "maxRight" 27 | // maxRight[i] is the maximum sum "contiguous subsequence" starting at index i 28 | // note: because it is "contiguous", we only need the starting index (important) 29 | for(int i=A.length-2; i >=0; i--){ // be careful: from i=A.length-2 (because of maxLeft[i+1]) 30 | maxRight[i] = Math.max(0, maxRight[i+1]+A[i] ); //golden slice algorithm: Math.max(0, maxRight[i+1]+A[i] ) 31 | } 32 | 33 | // 3) find the maximum of "maxLeft + maxRight" 34 | int maxDoubleSlice =0; 35 | for(int i=1; i < A.length-1; i++){ // where "i" means "Y" in this problem 36 | if(maxLeft[i-1] + maxRight[i+1] > maxDoubleSlice) // be careful: left end at "i-1" and right begins at "i+1" 37 | maxDoubleSlice = maxLeft[i-1] + maxRight[i+1]; // be careful: "not" maxLeft[i] + maxRight[i] 38 | } 39 | 40 | return maxDoubleSlice; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /MinAvgTwoSlice.java: -------------------------------------------------------------------------------- 1 | package MinAvgTwoSlice; 2 | 3 | // you can also use imports, for example: 4 | // import java.util.*; 5 | 6 | class Solution { 7 | public int solution(int[] A) { 8 | 9 | // main idea: 10 | // we know from the problem description 11 | // that the slices have a minimum length of 2. 12 | // The trick to this problem is 13 | // that the min average slice has "the length of 2 or 3" 14 | // So, we only need to calculate the avg of the slices of length 2 and 3 15 | 16 | // note: return the start position (of the min average slice) 17 | 18 | // note: because we will use "/", we need to use "float" (not "int") 19 | float min = Integer.MAX_VALUE; 20 | int min_start_position =0; // to store the start position 21 | 22 | // note: for "i< A.length -2" 23 | for(int i=0; i< A.length -2; i++){ 24 | 25 | // note: need to use "float" 26 | float avg_2 = (float) (A[i]+A[i+1])/2; // avg of length of 2 27 | float avg_3 = (float) (A[i]+A[i+1]+A[i+2])/3; // avg of length of 3 28 | 29 | // for debugging 30 | // System.out.println(i + " " + avg_2 + " " + avg_3); 31 | 32 | // take the smaller one 33 | float cur_min_avg = Math.min(avg_2, avg_3); 34 | 35 | // keep the smallest one 36 | if(cur_min_avg < min){ 37 | min = cur_min_avg; 38 | min_start_position = i; 39 | } 40 | } 41 | 42 | // note: for the last missing case 43 | // case: avg of length of 2 "A[A.length-2] + A[A.length-1]" 44 | int avg_2 = (A[A.length-2]+A[A.length-1]) / 2; 45 | if( avg_2 < min){ 46 | min = avg_2; 47 | min_start_position = A.length-2; 48 | } 49 | 50 | return min_start_position; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Ladder.java: -------------------------------------------------------------------------------- 1 | package Ladder; 2 | 3 | class Solution { 4 | public int[] solution(int[] A, int[] B) { 5 | 6 | // The task is to find out the number of ways 7 | // someone can climb up a ladder of N rungs 8 | // by ascending one or two rungs at a time. 9 | // It is not very hard to see that 10 | // this number is just the "Fibonacci number of order N" 11 | 12 | // we implemented an easy dynamic programming approach 13 | // to compute Fibonacci numbers, this will take complexity O(n) 14 | 15 | // I use binary operators to keep track of "N modulo 2^{30}" 16 | // otherwise. the Fibonacci numbers will cause a memory overflow (be careful~!!) 17 | // and we are also asked to return "numbers modulo some power of 2" 18 | 19 | int L = A.length; 20 | 21 | // determine the "max" for Fibonacci 22 | int max = 0; 23 | for (int i = 0; i < L; i++) { 24 | max = Math.max(A[i], max); 25 | } 26 | //max += 2; // for Fibonacci 27 | 28 | int[] fibonacci = new int[max+1]; // plus one for "0" 29 | 30 | // initial setting of Fibonacci (importnat) 31 | fibonacci[0] =1; 32 | fibonacci[1] =1; 33 | 34 | for(int i=2; i<= max; i++){ 35 | fibonacci[i] = (fibonacci[i-1] + fibonacci[i-2]) % (1 << 30); 36 | // we want to find the result of "a number modulo 2^P" 37 | // if we first let the number modulo 2^Q (Q > P) 38 | // then, modulo 2^P, the esult is the same. 39 | // So, "we first modulo 2^30" to avoid overflow 40 | // where, 2^30 == 1 << 30 41 | } 42 | 43 | // to find "results" 44 | int[] results = new int[L]; 45 | 46 | for(int i=0; i map1 = new HashMap<>(); 13 | // key: the elements, value, count of elements 14 | for(int i=0; i< A.length; i++){ 15 | if(map1.containsKey(A[i]) == false){ 16 | map1.put(A[i], 1); // add new element 17 | } 18 | else{ 19 | map1.put(A[i], map1.get(A[i])+1 ); // count++ 20 | } 21 | } 22 | 23 | // map2(key, value) 24 | HashMap map2 = new HashMap<>(); 25 | // key: the elements, value, count of "number of non-divisors" of elements 26 | for( int n : map1.keySet() ){ 27 | int numDivisors =0; 28 | // find divisors from 1 to sqrt(n) 29 | int sqrtN = (int)Math.sqrt(n); 30 | for(int i=1; i<=sqrtN; i++ ){ 31 | if( n % i == 0){ // means: i could be a divisor 32 | int anotherDivisor = n/i; 33 | 34 | if(map1.containsKey(i) == true ){ 35 | numDivisors = numDivisors + map1.get(i); 36 | } 37 | if(anotherDivisor != i){ // avoid double count (be careful) 38 | if(map1.containsKey(anotherDivisor) == true){ 39 | numDivisors = numDivisors + map1.get(anotherDivisor); 40 | } 41 | } 42 | } 43 | } 44 | 45 | int numNonDivisors = A.length - numDivisors; 46 | map2.put(n, numNonDivisors); 47 | } 48 | 49 | // results: number of non-divisors 50 | int[] results = new int[A.length]; 51 | for (int i = 0; i < A.length; i++) { 52 | results[i] = map2.get(A[i]); 53 | } 54 | 55 | return results; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /MaxCounters.java: -------------------------------------------------------------------------------- 1 | package MaxCounters; 2 | 3 | class Solution { 4 | public int[] solution(int N, int[] A) { 5 | // write your code in Java SE 8 6 | 7 | // 1. key point: maintain the max value 8 | int max = 0; 9 | 10 | // 2. key point: maintain the current_min (very important!!!) 11 | // so, we can move "the 2nd for-loop" outside "the 1st for-loop" 12 | // by maintaining "min" 13 | int min =0; 14 | 15 | // new integer array 16 | int[] my_array = new int[N]; 17 | 18 | /* no need to initialize (because the values are "0" by default) 19 | for(int i=0; i= 1 && A[i] <= N){ // normal case 26 | 27 | // important: check the "min" before "increasing by 1" 28 | if(my_array[ A[i] -1] < min){ 29 | my_array[ A[i] -1] = min; // update it to "min" 30 | } 31 | 32 | my_array[ A[i] -1 ] ++; // increased by 1 33 | 34 | if( my_array[ A[i] -1 ] > max){ // maintain max 35 | max = my_array[ A[i] -1 ]; 36 | } 37 | } 38 | else if( A[i] == N+1){ // special case 39 | /* cannot use for-loop (will take too much time) 40 | for(int j=0; j if yes, return the "number of groups" 14 | 15 | // use "List" to store all the peaks 16 | List peaksIndexList = new ArrayList<>(); 17 | 18 | // 1) find the peaks (and store them) 19 | for(int i=1; iA[i+1] ){ // A[i] > A[i-1], A[i] > A[i+1] 21 | peaksIndexList.add(i); 22 | } 23 | } 24 | 25 | // 2) check the number of Blocks 26 | int N = A.length; 27 | 28 | // from the "biggest possible number" to smaller number 29 | for(int numBlocks =N; numBlocks >=1; numBlocks--){ 30 | 31 | if( N % numBlocks ==0){ // it is divisible 32 | 33 | int blockSize = N / numBlocks; 34 | int ithOkBlock =0; // the ith block has peak(s) 35 | 36 | // test all the peaks 37 | // if a peak is found in the ith block 38 | // then, go to the (i+1)th block 39 | for(int peaksIndex : peaksIndexList){ 40 | if( peaksIndex/blockSize == ithOkBlock){ // peak in the ith block 41 | ithOkBlock++; // go to check (i+1)th block 42 | } 43 | } 44 | 45 | // ithOkBlock: the number of blocks having peak(s) 46 | // if all the blocks have peak(s) 47 | // then, return the number of blocks 48 | // note: we test from the biggest possible number 49 | // so, once we find it, we can just return it 50 | // (no need to check the smaller possible numbers) 51 | if(ithOkBlock == numBlocks){ 52 | return numBlocks; 53 | } 54 | } 55 | } 56 | 57 | return 0; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /MaxSliceSum_Solution_2.java: -------------------------------------------------------------------------------- 1 | // This solution is a bit "ugly" (but 100%/100% correctness/performance) 2 | 3 | package MaxSliceSum; 4 | 5 | class Solution { 6 | public int solution(int[] A) { 7 | 8 | // main idea: 9 | // use "golden slice algorithm" O(n) 10 | // take maxEnding[i] = Math.max( 0, maxEnding[i-1] + A[i] ) <--- important~!! 11 | // explanation : 12 | // At the end of each slice, we decide whether its value 13 | // is going to be carried to the next element's computation 14 | // based on whether the value is "negative or positive". <--- "key point" 15 | // If positive, we carry it (so it contributes to the next slice) 16 | // Otherwise we start from "0" 17 | 18 | // need to be careful about special cases 19 | // special case 1: one element 20 | if(A.length ==1) 21 | return A[0]; 22 | // special case 2: all the elements are "negative" 23 | // for case 2: the maximum is equal to the "single max element" 24 | boolean negtiveCase = true; 25 | for(int i=0; i< A.length; i++){ 26 | if(A[i] > 0) 27 | negtiveCase = false; 28 | } 29 | if( negtiveCase == true){ 30 | int max = Integer.MIN_VALUE; // use "Integer.MIN_VALUE" 31 | for(int i=0; i max) 33 | max = A[i]; 34 | } 35 | return max; 36 | } 37 | 38 | // 1) find maxEnding[] 39 | int maxEnding[] = new int[A.length]; 40 | 41 | if(A[0] < 0) // <--- very important (be careful) 42 | maxEnding[0] = 0; 43 | else 44 | maxEnding[0] = A[0]; 45 | 46 | for(int i=1; i maxSlice) 55 | maxSlice = maxEnding[i]; 56 | } 57 | 58 | return maxSlice; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /MinMaxDivision.java: -------------------------------------------------------------------------------- 1 | package MinMaxDivision; 2 | 3 | class Solution { 4 | public int solution(int K, int M, int[] A) { 5 | 6 | // main idea: 7 | // The goal is to find the "minimal large sum" 8 | // We use "binary search" to find it (so, it can be fast) 9 | 10 | // We assume that the "min max Sum" will be 11 | // between "min" and "max", ecah time we try "mid" 12 | 13 | int minSum =0; 14 | int maxSum =0; 15 | for(int i=0; i max" 43 | } 44 | 45 | return possibleResult; 46 | } 47 | 48 | // check if it can be divided by using the minMaxSum = "mid", into K blocks ? 49 | public boolean checkDivisable(int mid, int k, int[] a){ 50 | int numBlockAllowed = k; 51 | int currentBlockSum = 0; 52 | 53 | for(int i=0; i< a.length; i++){ 54 | currentBlockSum = currentBlockSum + a[i]; 55 | 56 | if(currentBlockSum > mid){ // means: need one more block 57 | numBlockAllowed--; 58 | currentBlockSum = a[i]; // note: next block 59 | } 60 | 61 | if(numBlockAllowed == 0){ 62 | return false; // cannot achieve minMaxSum = "mid" 63 | } 64 | } 65 | 66 | // can achieve minMaxSum = "mid" 67 | return true; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /GenomicRangeQuery.java: -------------------------------------------------------------------------------- 1 | package GenomicRangeQuery; 2 | 3 | class Solution { 4 | public int[] solution(String S, int[] P, int[] Q) { 5 | 6 | // result: the minimal impact of each query 7 | int[] result = new int[P.length]; 8 | 9 | // to count "A"、"C"、"G"、"T" 10 | // A[i] means: num of 'a' from 0 to i-1 11 | int A[] = new int[S.length()+1]; 12 | int C[] = new int[S.length()+1]; 13 | int G[] = new int[S.length()+1]; 14 | int T[] = new int[S.length()+1]; 15 | // note: we use "S.length()+1" 16 | // which will let A[0]=0, C[0]=0, G[0]=0, T[0]=0 17 | // becasue we will compute number of 'a' by "A[Q+1] - A[P]" 18 | // we actually shift to right by one, and assume the biginning is a dummy '0' 19 | 20 | // counting ( note: A[0]=0, C[0]=0, G[0]=0, T[0]=0 ) 21 | for (int i = 0; i < S.length(); i++) { 22 | if(S.charAt(i) == 'A') 23 | { 24 | A[i+1] = A[i]+1; 25 | C[i+1] = C[i]; 26 | G[i+1] = G[i]; 27 | T[i+1] = T[i]; 28 | } 29 | else if(S.charAt(i) == 'C') 30 | { 31 | A[i+1] = A[i]; 32 | C[i+1] = C[i]+1; 33 | G[i+1] = G[i]; 34 | T[i+1] = T[i]; 35 | } 36 | else if(S.charAt(i) == 'G') 37 | { 38 | A[i+1] = A[i]; 39 | C[i+1] = C[i]; 40 | G[i+1] = G[i]+1; 41 | T[i+1] = T[i]; 42 | } 43 | else if(S.charAt(i) == 'T') 44 | { 45 | A[i+1] = A[i]; 46 | C[i+1] = C[i]; 47 | G[i+1] = G[i]; 48 | T[i+1] = T[i]+1; 49 | } 50 | } 51 | 52 | // to handle the queries 53 | int num_of_query = P.length; // or Q.length 54 | for (int i = 0; i < num_of_query; i++) { 55 | int a = A[ Q[i] + 1] - A[ P[i] ]; // num of 'a' between P and Q 56 | int c = C[ Q[i] + 1] - C[ P[i] ]; // num of 'c' between P and Q 57 | int g = G[ Q[i] + 1] - G[ P[i] ]; // num of 'g' between P and Q 58 | 59 | if(a > 0){ // there is 'a' 60 | result[i] = 1; 61 | } 62 | else if(c > 0){ // there is 'c' 63 | result[i] = 2; 64 | } 65 | else if(g > 0){ // there is 'g' 66 | result[i] =3; 67 | } 68 | else{ // there is only 'T' 69 | result[i] =4; 70 | } 71 | } 72 | 73 | return result; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /CountSemiprimes.java: -------------------------------------------------------------------------------- 1 | package CountSemiprimes; 2 | 3 | import java.util.*; 4 | 5 | class Solution { 6 | public int[] solution(int N, int[] P, int[] Q) { 7 | 8 | // main idea: 9 | // using "sieve of Eratosthenes" 10 | // https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 11 | 12 | boolean[] primeArray = new boolean[N+1]; // note: plus one for "0" 13 | 14 | // initial settting (sieve of Eratosthenes) 15 | Arrays.fill(primeArray, true); // initial setting: all primes 16 | primeArray[0] = false; // not prime 17 | primeArray[1] = false; // not prime 18 | int sqrtN = (int)Math.sqrt(N); 19 | // sieve of Eratosthenes 20 | for(int i =1; i < sqrtN; i++){ 21 | if(primeArray[i] == true) // prime 22 | { 23 | int j = i + i; 24 | for(j=j; j<=N; j=j+i){ 25 | primeArray[j] = false; // not prime 26 | } 27 | } 28 | } 29 | 30 | // store all primes in "List" 31 | List primeList = new ArrayList<>(); 32 | for(int i=2; i<= N; i++){ 33 | if(primeArray[i] == true){ 34 | primeList.add(i); // "i" is prime 35 | } 36 | } 37 | 38 | // find "semiprimes" 39 | boolean[] semiprimeArray = new boolean[N+1]; // note: plus one for "0" 40 | Arrays.fill(semiprimeArray, false); // initial setting: all "not" semiprimes 41 | long semiprimeTemp; // using "long" (be careful) 42 | // for "primeList.size()" 43 | for(int i=0; i< primeList.size(); i++){ 44 | for(int j=i; j< primeList.size(); j++){ 45 | semiprimeTemp = (long) primeList.get(i) * (long) primeList.get(j); // semiprimes 46 | if(semiprimeTemp > N){ 47 | break; 48 | } 49 | else{ 50 | semiprimeArray[(int)semiprimeTemp] = true; // semiprimes 51 | } 52 | } 53 | } 54 | 55 | // compute "cumulative Count of semiprimes" 56 | int[] semiprimeCumulateCount = new int [N+1]; // note: plus one for "0" 57 | for(int i=1; i<=N; i++){ 58 | semiprimeCumulateCount[i] = semiprimeCumulateCount[i-1]; // cumulative 59 | if(semiprimeArray[i] == true){ 60 | semiprimeCumulateCount[i]++; // semiprimes 61 | } 62 | } 63 | 64 | // compute "results" (for each query) 65 | int numQuery = Q.length; 66 | int[] result = new int[numQuery]; 67 | for(int i=0; i< numQuery; i++){ 68 | result[i] = semiprimeCumulateCount[Q[i]] - semiprimeCumulateCount[P[i]-1]; // note: "P[i]-1" (not included) 69 | } 70 | return result; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /FibFrog.java: -------------------------------------------------------------------------------- 1 | package FibFrog; 2 | 3 | import java.util.*; 4 | // for using "point" (java.awt.*) 5 | import java.awt.*; 6 | 7 | class Solution { 8 | public int solution(int[] A) { 9 | 10 | // note: cannot use "List" (both java.util.* and java.awt.* have "List") 11 | ArrayList fibonacci = new ArrayList<>(); 12 | fibonacci.add(0); // note: f(0) = 0 (as in the quesion) 13 | fibonacci.add(1); 14 | // note: using "while" is better than "for" (avoid errors) 15 | while(true){ 16 | int temp1 = fibonacci.get( fibonacci.size()-1 ); 17 | int temp2 = fibonacci.get( fibonacci.size()-2 ); 18 | fibonacci.add( temp1 + temp2 ); 19 | 20 | // if already bigger than length, then break; 21 | if(temp1 + temp2 > A.length){ 22 | break; 23 | } 24 | } 25 | 26 | // reverse "List": from big to small 27 | Collections.reverse(fibonacci); 28 | 29 | // use "queue" with "point" 30 | // point(x,y) = point("position", "number of steps") 31 | ArrayList queue = new ArrayList<>(); 32 | queue.add( new Point(-1, 0) ); // position:-1, steps:0 33 | 34 | // index: the current index for queue element 35 | int index=0; 36 | while(true){ 37 | // cannot take element from queue anymore 38 | if(index == queue.size() ){ 39 | return -1; 40 | } 41 | 42 | // take element from queue 43 | Point current = queue.get(index); 44 | 45 | // from big to small 46 | for(Integer n: fibonacci){ 47 | int nextPosition = current.x + n; 48 | 49 | // case 1: "reach the other side" 50 | if(nextPosition == A.length){ 51 | // return the number of steps 52 | return current.y + 1; 53 | } 54 | 55 | // case 2: "cannot jump" 56 | // note: nextPosition < 0 (overflow, be careful) 57 | else if( (nextPosition > A.length) || (nextPosition < 0)|| (A[nextPosition]==0) ){ 58 | // note: do nothing 59 | } 60 | 61 | // case 3: "can jump" (othe cases) 62 | else{ 63 | // jump to next position, and step+1 64 | Point temp = new Point(nextPosition, current.y + 1); 65 | // add to queue 66 | queue.add(temp); 67 | 68 | A[nextPosition] = 0; // key point: for high performance~!! 69 | } 70 | } 71 | 72 | index++; // take "next element" from queue 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /EquiLeader.java: -------------------------------------------------------------------------------- 1 | package EquiLeader; 2 | 3 | // you can also use imports, for example: 4 | import java.util.*; 5 | 6 | class Solution { 7 | public int solution(int[] A) { 8 | 9 | // special case 10 | if( A.length ==0) 11 | return 0; 12 | 13 | // The key point: 14 | // Only the "leader of the whole array" can have an "equi leader" 15 | // Assume a value Y is "not" the leader of the whole array. 16 | // Can value Y have an equi leader? 17 | // The answer is NO. 18 | 19 | // Based on this condition, to solve this problem, 20 | // 1. we first find the leader of the whole array. 21 | // 2. after finding a leader (if any), 22 | // we then scan the whole array again. 23 | 24 | // 1. find the leader of an array 25 | // ---> we use "hashMap" 26 | Map map = new HashMap<>(); 27 | 28 | // map(key, value) ---> map(number, count) 29 | for(int i=0; i max_Count){ 45 | max_Count = cur_Count; 46 | max_Value = j; 47 | } 48 | } 49 | 50 | // check "if there is a leader" 51 | int leader_Value =0; 52 | int leader_Count =0; 53 | if( max_Count > (0.5) * (A.length) ){ 54 | leader_Value = max_Value; 55 | leader_Count = max_Count; 56 | } 57 | else{ 58 | return 0; // no leader ---> no equi leaders 59 | } 60 | 61 | // note: cannot use (1/2) * (A.length) 62 | // This is because (1/2) will be "zeor" 63 | // Instead, we can use (0.5) * (A.length) (be careful) 64 | 65 | // 2. scan the whole array again 66 | int num_Equi_leaders = 0; // number of equi leaders 67 | int left_Leader_Count =0; // number of leaders in left side 68 | 69 | // scan the array 70 | for(int i=0; i (0.5) * (i+1) ){ 79 | // then, check right side 80 | int right_Leader_Count = leader_Count - left_Leader_Count; 81 | // if the leader is "a leader in right side" (more than half) 82 | if( right_Leader_Count > (0.5) * (A.length -i -1) ){ 83 | num_Equi_leaders++; // leader in both sides (then, equi leaders++) 84 | } 85 | } 86 | } 87 | // return number of equi leaders 88 | return num_Equi_leaders; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Codility 2 | My Solutions to [Codility Lessons](https://codility.com/programmers/lessons/1-iterations/) 3 | can be found in [My Blog](http://chienchikao.blogspot.tw/) and are listed as follows (100% performance with comments) : 4 | 5 | Lesson 1 Iterations 6 | - [BinaryGap](https://github.com/Mickey0521/Codility/blob/master/BinaryGap.java) 7 | 8 | Lesson 2 Arrays 9 | - [OddOccurrencesInArray](https://github.com/Mickey0521/Codility/blob/master/OddOccurrencesInArray.java) 10 | - [CyclicRotation](https://github.com/Mickey0521/Codility/blob/master/CyclicRotation.java) 11 | 12 | Lesson 3 Time Complexity 13 | - [FrogJmp](https://github.com/Mickey0521/Codility/blob/master/FrogJmp.java) 14 | - [PermMissingElem](https://github.com/Mickey0521/Codility/blob/master/PermMissingElem.java) 15 | - [TapeEquilibrium](https://github.com/Mickey0521/Codility/blob/master/TapeEquilibrium.java) 16 | 17 | Lesson 4 Counting Elements 18 | - [PermCheck](https://github.com/Mickey0521/Codility/blob/master/PermCheck.java) 19 | - [FrogRiverOne](https://github.com/Mickey0521/Codility/blob/master/FrogRiverOne.java) 20 | - [MissingInteger](https://github.com/Mickey0521/Codility/blob/master/MissingInteger.java) 21 | - [MaxCounters](https://github.com/Mickey0521/Codility/blob/master/MaxCounters.java) (respectable) 22 | 23 | Lesson 5 Prefix Sums 24 | - [CountDiv](https://github.com/Mickey0521/Codility/blob/master/CountDiv.java) 25 | - [PassingCars](https://github.com/Mickey0521/Codility/blob/master/PassingCars.java) 26 | - [GenomicRangeQuery](https://github.com/Mickey0521/Codility/blob/master/GenomicRangeQuery.java) (respectable) 27 | - [MinAvgTwoSlice](https://github.com/Mickey0521/Codility/blob/master/MinAvgTwoSlice.java) (respectable) 28 | 29 | Lesson 6 Sorting 30 | - [Distinct](https://github.com/Mickey0521/Codility/blob/master/Distinct.java) 31 | - [Triangle](https://github.com/Mickey0521/Codility/blob/master/Triangle.java) 32 | - [MaxProductOfThree](https://github.com/Mickey0521/Codility/blob/master/MaxProductOfThree.java) 33 | - [NumberOfDiscIntersections](https://github.com/Mickey0521/Codility/blob/master/NumberOfDiscIntersections.java) (respectable) 34 | 35 | Lesson 7 Stacks and Queues 36 | - [StoneWall](https://github.com/Mickey0521/Codility/blob/master/StoneWall.java) 37 | - [Brackets](https://github.com/Mickey0521/Codility/blob/master/Brackets.java) 38 | - [Nesting](https://github.com/Mickey0521/Codility/blob/master/Nesting.java) 39 | - [Fish](https://github.com/Mickey0521/Codility/blob/master/Fish.java) 40 | 41 | Lesson 8 Leader 42 | - [EquiLeader](https://github.com/Mickey0521/Codility/blob/master/EquiLeader.java) 43 | - [Dominator](https://github.com/Mickey0521/Codility/blob/master/Dominator.java) 44 | 45 | Lesson 9 Maximum slice problem 46 | - [MaxDoubleSliceSum](https://github.com/Mickey0521/Codility/blob/master/MaxDoubleSliceSum.java) 47 | - [MaxProfit](https://github.com/Mickey0521/Codility/blob/master/MaxProfit.java) 48 | - [MaxSliceSum](https://github.com/Mickey0521/Codility/blob/master/MaxSliceSum.java) 49 | 50 | Lesson 10 Prime and composite numbers 51 | - [MinPerimeterRectangle](https://github.com/Mickey0521/Codility/blob/master/MinPerimeterRectangle.java) 52 | - [CountFactors](https://github.com/Mickey0521/Codility/blob/master/CountFactors.java) 53 | - [Peaks](https://github.com/Mickey0521/Codility/blob/master/Peaks.java) (respectable) 54 | - Flags (respectable) 55 | 56 | Lesson 11 Sieve of Eratosthenes 57 | - [CountSemiprimes](https://github.com/Mickey0521/Codility/blob/master/CountSemiprimes.java) 58 | - [CountNonDivisible](https://github.com/Mickey0521/Codility/blob/master/CountNonDivisible.java) (respectable) 59 | 60 | Lesson 12 Euclidean algorithm 61 | - [ChocolatesByNumbers](https://github.com/Mickey0521/Codility/blob/master/ChocolatesByNumbers_SimpleLowPerformance.java) 62 | - CommonPrimeDivisors (respectable) 63 | 64 | Lesson 13 Fibonacci numbers 65 | - [Ladder](https://github.com/Mickey0521/Codility/blob/master/Ladder.java) (respectable) 66 | - [FibFrog](https://github.com/Mickey0521/Codility/blob/master/FibFrog.java) (respectable) 67 | 68 | Lesson 14 Binary search algorithm 69 | - [MinMaxDivision](https://github.com/Mickey0521/Codility/blob/master/MinMaxDivision.java) (respectable) 70 | - NailingPlanks (respectable) 71 | 72 | Lesson 15 Caterpillar method 73 | - [AbsDistinct](https://github.com/Mickey0521/Codility/blob/master/AbsDistinct.java) 74 | - [CountDistinctSlices](https://github.com/Mickey0521/Codility/blob/master/CountDistinctSlices.java) 75 | - [CountTriangles](https://github.com/Mickey0521/Codility/blob/master/CountTriangles.java) 76 | - MinAbsSumOfTwo (respectable) 77 | 78 | Lesson 16 Greedy algorithms 79 | - [MaxNonoverlappingSegments](https://github.com/Mickey0521/Codility/blob/master/MaxNonoverlappingSegments.java) 80 | - [TieRopes](https://github.com/Mickey0521/Codility/blob/master/TieRopes.java) 81 | 82 | Lesson 17 Dynamic programming 83 | - [NumberSolitaire](https://github.com/Mickey0521/Codility/blob/master/NumberSolitaire.java) (respectable) 84 | - MinAbsSum (ambitious) 85 | --------------------------------------------------------------------------------