├── _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 |
--------------------------------------------------------------------------------