Your browser is not supported. Please, update your browser or switch to a different one. Learn more about which browsers are supported.
Task description
Winter is coming and Victor is going to buy some new lights. In the store, lights are available in 10 colors, numbered from 0 to 9. They are connected together in a huge chain. Victor can choose any single segment of the chain and buy it.
This task would be easy if it weren't for Victor's ambition. He wants to outdo his neighbors with some truly beautiful lights, so the chain has to look the same from both its left and right sides (so that both neighbors see the same effect).
Victor is a mechanic, so after buying a segment of the chain, he can rearrange its lights in any order he wants. However, now he has to buy a chain segment that will satisfy above condition when its lights are reordered. Can you compute how many possible segments he can choose from?
Write a function:
class Solution { public int solution(String S); }
that, given a description of the chain of lights, returns the number of segments that Victor can buy modulo 1,000,000,007. The chain is represented by a string of digits (characters from '0' to '9') of length N. The digits represent the colors of the lights. Victor can only buy a segment of the chain in which he can reorder the lights such that the chain will look identical from both the left and right sides (i.e. when reversed).
For example, given:
S = "02002"the function should return 11. Victor can buy the following segments of the chain:
"0", "2", "0", "0", "2", "00", "020", "200", "002", "2002", "02002"Note that a segment comprising a single "0" is counted three times: first it describes the subchain consisting of only the first light, then the subchain consisting of the third light and finally the subchain consisting of the fourth light. Also note that Victor can buy the whole chain ("02002"), as, after swapping the first two lights, it would become "20002", which is the same when seen from both from left and right.
Write an efficient algorithm for the following assumptions:
- string S is made only of digits (0−9);
- the length of string S is within the range [1..200,000].
Task timeline
// you can also use imports, for example:
// import java.util.*;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int solution(String s) {
int n = s.length();
AtomicInteger total = new AtomicInteger(0);
IntStream.range(0, n-1).parallel().forEach( i ->
IntStream.range(i+2, n+1).parallel().forEach(j ->
{ if(isPalindrome(s.substring(i,j)))
total.incrementAndGet();
})
);
return total.get() + n;
}
static boolean isPalindrome(String s) {
if(s == null) return false;
int[] c = new int[10];
for(int i=0; i<s.length(); i++) {
int num = s.charAt(i) - '0';
c[num] = c[num] ^ 1;
}
int total = 0;
for(int i : c) total += i;
if(s.length() % 2 == 0) {
return (total == 0) ? true : false;
} else {
return (total == 1) ? true : false;
}
}
}
Solution.java:10: error: cannot find symbol AtomicInteger total = new AtomicInteger(0); ^ symbol: class AtomicInteger location: class Solution Solution.java:10: error: cannot find symbol AtomicInteger total = new AtomicInteger(0); ^ symbol: class AtomicInteger location: class Solution Solution.java:11: error: cannot find symbol IntStream.range(0, n-1).parallel().forEach( i -> ^ symbol: variable IntStream location: class Solution Solution.java:12: error: cannot find symbol IntStream.range(i+2, n+1).parallel().forEach(j -> ^ symbol: variable IntStream location: class Solution 4 errors
// you can also use imports, for example:
// import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int solution(String s) {
int n = s.length();
AtomicInteger total = new AtomicInteger(0);
IntStream.range(0, n-1).parallel().forEach( i ->
IntStream.range(i+2, n+1).parallel().forEach(j ->
{ if(isPalindrome(s.substring(i,j)))
total.incrementAndGet();
})
);
return total.get() + n;
}
static boolean isPalindrome(String s) {
if(s == null) return false;
int[] c = new int[10];
for(int i=0; i<s.length(); i++) {
int num = s.charAt(i) - '0';
c[num] = c[num] ^ 1;
}
int total = 0;
for(int i : c) total += i;
if(s.length() % 2 == 0) {
return (total == 0) ? true : false;
} else {
return (total == 1) ? true : false;
}
}
}
// you can also use imports, for example:
// import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int solution(String s) {
int n = s.length();
AtomicInteger total = new AtomicInteger(0);
IntStream.range(0, n-1).parallel().forEach( i ->
IntStream.range(i+2, n+1).parallel().forEach(j ->
{ if(isPalindrome(s.substring(i,j)))
total.incrementAndGet();
})
);
return total.get() + n;
}
static boolean isPalindrome(String s) {
if(s == null) return false;
int[] c = new int[10];
for(int i=0; i<s.length(); i++) {
int num = s.charAt(i) - '0';
c[num] = c[num] ^ 1;
}
int total = 0;
for(int i : c) total += i;
if(s.length() % 2 == 0) {
return (total == 0) ? true : false;
} else {
return (total == 1) ? true : false;
}
}
}
// you can also use imports, for example:
// import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int solution(String s) {
int n = s.length();
AtomicInteger total = new AtomicInteger(0);
IntStream.range(0, n-1).parallel().forEach( i ->
IntStream.range(i+2, n+1).parallel().forEach(j ->
{ if(isPalindrome(s.substring(i,j)))
total.incrementAndGet();
})
);
return total.get() + n;
}
static boolean isPalindrome(String s) {
if(s == null) return false;
int[] c = new int[10];
for(int i=0; i<s.length(); i++) {
int num = s.charAt(i) - '0';
c[num] = c[num] ^ 1;
}
int total = 0;
for(int i : c) total += i;
if(s.length() % 2 == 0) {
return (total == 0) ? true : false;
} else {
return (total == 1) ? true : false;
}
}
}
The following issues have been detected: timeout errors.
medium correctness tests (length = 100)
running time: 0.84 sec., time limit: 0.62 sec.
big correctness tests (length = 300)
running time: 2.13 sec., time limit: 0.37 sec.
big correctness tests (length = 1000)
running time: >6.00 sec., time limit: 0.53 sec.
large correctness tests (length = 50 000)
running time: >6.00 sec., time limit: 0.99 sec.
max correctness tests (length = 200 000)
running time: >7.00 sec., time limit: 1.64 sec.
tests with increasing value of N and varying alphabet size
running time: >6.00 sec., time limit: 0.47 sec.
tests detecting lack of int64 in solutions
running time: >8.00 sec., time limit: 2.17 sec.
tests introducting special words, e.g. Fibonacci, Thue-Morse, Gray codes
running time: >8.00 sec., time limit: 2.44 sec.