How to speed up first unique character lookup
up vote
1
down vote
favorite
I'm solving 387. First Unique Character in a String LeetCode problem defined as:
Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1.
Examples:
s = "leetcode"
return 0.
s = "loveleetcode",
return 2.
Note: You may assume the string contain only lowercase letters.
Taking advantage of the input being fully lowercase ASCII I created two bit vectors to track when we encounter a character for the first and second time.
Can below code be improved further? LeetCode says that below code is better than 94.33% solutions. What else could have been done by the last 5.67% solutions that they were better?
class Solution {
public int firstUniqChar(String s) {
int firstSpot = 0;
int secondSpot = 0;
char chars = s.toCharArray();
for (char c : chars) {
int mask = 1 << c - 'a';
if ((firstSpot & mask) == 0) {
firstSpot |= mask;
} else if ((secondSpot & mask) == 0) {
secondSpot |= mask;
}
}
int i = 0;
for (char c : chars) {
int mask = 1 << c - 'a';
if ((secondSpot & mask) == 0) {
return i;
}
i++;
}
return -1;
}
}
Are there tricks that can be done to improve the LeetCode score? It seems that enhanced for-each
loop performs better than standard for
loop but I can't prove it, It's an observation based on few of my previous submissions.
java algorithm
add a comment |
up vote
1
down vote
favorite
I'm solving 387. First Unique Character in a String LeetCode problem defined as:
Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1.
Examples:
s = "leetcode"
return 0.
s = "loveleetcode",
return 2.
Note: You may assume the string contain only lowercase letters.
Taking advantage of the input being fully lowercase ASCII I created two bit vectors to track when we encounter a character for the first and second time.
Can below code be improved further? LeetCode says that below code is better than 94.33% solutions. What else could have been done by the last 5.67% solutions that they were better?
class Solution {
public int firstUniqChar(String s) {
int firstSpot = 0;
int secondSpot = 0;
char chars = s.toCharArray();
for (char c : chars) {
int mask = 1 << c - 'a';
if ((firstSpot & mask) == 0) {
firstSpot |= mask;
} else if ((secondSpot & mask) == 0) {
secondSpot |= mask;
}
}
int i = 0;
for (char c : chars) {
int mask = 1 << c - 'a';
if ((secondSpot & mask) == 0) {
return i;
}
i++;
}
return -1;
}
}
Are there tricks that can be done to improve the LeetCode score? It seems that enhanced for-each
loop performs better than standard for
loop but I can't prove it, It's an observation based on few of my previous submissions.
java algorithm
2
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 at 23:03
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 at 23:04
1
Re: "LeetCode says that below code is better than 94.33% solutions": My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors (such as the other load on their servers at submission-time). So I'm not sure this figure is meant to be taken very seriously.
– ruakh
Nov 20 at 0:25
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I'm solving 387. First Unique Character in a String LeetCode problem defined as:
Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1.
Examples:
s = "leetcode"
return 0.
s = "loveleetcode",
return 2.
Note: You may assume the string contain only lowercase letters.
Taking advantage of the input being fully lowercase ASCII I created two bit vectors to track when we encounter a character for the first and second time.
Can below code be improved further? LeetCode says that below code is better than 94.33% solutions. What else could have been done by the last 5.67% solutions that they were better?
class Solution {
public int firstUniqChar(String s) {
int firstSpot = 0;
int secondSpot = 0;
char chars = s.toCharArray();
for (char c : chars) {
int mask = 1 << c - 'a';
if ((firstSpot & mask) == 0) {
firstSpot |= mask;
} else if ((secondSpot & mask) == 0) {
secondSpot |= mask;
}
}
int i = 0;
for (char c : chars) {
int mask = 1 << c - 'a';
if ((secondSpot & mask) == 0) {
return i;
}
i++;
}
return -1;
}
}
Are there tricks that can be done to improve the LeetCode score? It seems that enhanced for-each
loop performs better than standard for
loop but I can't prove it, It's an observation based on few of my previous submissions.
java algorithm
I'm solving 387. First Unique Character in a String LeetCode problem defined as:
Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1.
Examples:
s = "leetcode"
return 0.
s = "loveleetcode",
return 2.
Note: You may assume the string contain only lowercase letters.
Taking advantage of the input being fully lowercase ASCII I created two bit vectors to track when we encounter a character for the first and second time.
Can below code be improved further? LeetCode says that below code is better than 94.33% solutions. What else could have been done by the last 5.67% solutions that they were better?
class Solution {
public int firstUniqChar(String s) {
int firstSpot = 0;
int secondSpot = 0;
char chars = s.toCharArray();
for (char c : chars) {
int mask = 1 << c - 'a';
if ((firstSpot & mask) == 0) {
firstSpot |= mask;
} else if ((secondSpot & mask) == 0) {
secondSpot |= mask;
}
}
int i = 0;
for (char c : chars) {
int mask = 1 << c - 'a';
if ((secondSpot & mask) == 0) {
return i;
}
i++;
}
return -1;
}
}
Are there tricks that can be done to improve the LeetCode score? It seems that enhanced for-each
loop performs better than standard for
loop but I can't prove it, It's an observation based on few of my previous submissions.
java algorithm
java algorithm
asked Nov 19 at 23:00
Karol Dowbecki
14k72746
14k72746
2
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 at 23:03
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 at 23:04
1
Re: "LeetCode says that below code is better than 94.33% solutions": My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors (such as the other load on their servers at submission-time). So I'm not sure this figure is meant to be taken very seriously.
– ruakh
Nov 20 at 0:25
add a comment |
2
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 at 23:03
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 at 23:04
1
Re: "LeetCode says that below code is better than 94.33% solutions": My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors (such as the other load on their servers at submission-time). So I'm not sure this figure is meant to be taken very seriously.
– ruakh
Nov 20 at 0:25
2
2
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 at 23:03
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 at 23:03
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 at 23:04
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 at 23:04
1
1
Re: "LeetCode says that below code is better than 94.33% solutions": My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors (such as the other load on their servers at submission-time). So I'm not sure this figure is meant to be taken very seriously.
– ruakh
Nov 20 at 0:25
Re: "LeetCode says that below code is better than 94.33% solutions": My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors (such as the other load on their servers at submission-time). So I'm not sure this figure is meant to be taken very seriously.
– ruakh
Nov 20 at 0:25
add a comment |
3 Answers
3
active
oldest
votes
up vote
2
down vote
I got 98.58% with this:-
public int firstUniqChar(String s) {
int count = new int[122 - 96];
final char chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
count[chars[i] - 97]++;
}
for (int i = 0; i < chars.length; i++) {
if (count[chars[i] - 97] == 1)
return i;
}
return -1;
}
You can get it to 100% by addingint setup=( {cin.tie(0);ios_base::sync_with_stdio(false);return 0;})();
to the beginning of the code.
– 0x499602D2
Nov 20 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 at 2:45
add a comment |
up vote
1
down vote
As @Ruakh says in a comment, the precise timings produced by leetcode are subject to a certain amount of randomness, so they should be taken with a grain of salt:
My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors.
Still, it is possible to speed your first loop up quite a bit by getting rid of the tests. The following loop is functionally equivalent; although it sets the variables more often, changing the value of a local integer variable costs less than testing whether it is necessary to change:
for (char c : chars) {
int mask = 1 << c - 'a';
secondSpot |= mask & firstSpot;
firstSpot |= mask;
}
(It's important that the assignment be in that order, so that the first one does nothing if the character hasn't yet been seen.)
add a comment |
up vote
1
down vote
Use this:
import java.util.Arrays;
class Solution {
// 0x60 < 'a' < 'z' < 0x80
private final byte bCounter = new byte[0x80];
private final int iCounter = new int[0x80];
public int firstUniqChar(String s) {
int len = s.length();
if ((len & 0xff) == len) {
Arrays.fill(bCounter, 0x60, 0x80, (byte)-1);
for (int i = 0; i < len; i++)
bCounter[s.charAt(i)]++;
for (int i = 0; i < len; i++)
if (bCounter[s.charAt(i)] == 0)
return i;
} else {
Arrays.fill(iCounter, 0x60, 0x80, -1);
for (int i = 0; i < len; i++)
iCounter[s.charAt(i)]++;
for (int i = 0; i < len; i++)
if (iCounter[s.charAt(i)] == 0)
return i;
}
return -1;
}
}
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
I got 98.58% with this:-
public int firstUniqChar(String s) {
int count = new int[122 - 96];
final char chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
count[chars[i] - 97]++;
}
for (int i = 0; i < chars.length; i++) {
if (count[chars[i] - 97] == 1)
return i;
}
return -1;
}
You can get it to 100% by addingint setup=( {cin.tie(0);ios_base::sync_with_stdio(false);return 0;})();
to the beginning of the code.
– 0x499602D2
Nov 20 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 at 2:45
add a comment |
up vote
2
down vote
I got 98.58% with this:-
public int firstUniqChar(String s) {
int count = new int[122 - 96];
final char chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
count[chars[i] - 97]++;
}
for (int i = 0; i < chars.length; i++) {
if (count[chars[i] - 97] == 1)
return i;
}
return -1;
}
You can get it to 100% by addingint setup=( {cin.tie(0);ios_base::sync_with_stdio(false);return 0;})();
to the beginning of the code.
– 0x499602D2
Nov 20 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 at 2:45
add a comment |
up vote
2
down vote
up vote
2
down vote
I got 98.58% with this:-
public int firstUniqChar(String s) {
int count = new int[122 - 96];
final char chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
count[chars[i] - 97]++;
}
for (int i = 0; i < chars.length; i++) {
if (count[chars[i] - 97] == 1)
return i;
}
return -1;
}
I got 98.58% with this:-
public int firstUniqChar(String s) {
int count = new int[122 - 96];
final char chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
count[chars[i] - 97]++;
}
for (int i = 0; i < chars.length; i++) {
if (count[chars[i] - 97] == 1)
return i;
}
return -1;
}
answered Nov 20 at 0:19
Kartik
2,47431331
2,47431331
You can get it to 100% by addingint setup=( {cin.tie(0);ios_base::sync_with_stdio(false);return 0;})();
to the beginning of the code.
– 0x499602D2
Nov 20 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 at 2:45
add a comment |
You can get it to 100% by addingint setup=( {cin.tie(0);ios_base::sync_with_stdio(false);return 0;})();
to the beginning of the code.
– 0x499602D2
Nov 20 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 at 2:45
You can get it to 100% by adding
int setup=( {cin.tie(0);ios_base::sync_with_stdio(false);return 0;})();
to the beginning of the code.– 0x499602D2
Nov 20 at 2:44
You can get it to 100% by adding
int setup=( {cin.tie(0);ios_base::sync_with_stdio(false);return 0;})();
to the beginning of the code.– 0x499602D2
Nov 20 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 at 2:45
@0x499602D2 java equivalent please
– Kartik
Nov 20 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 at 2:45
add a comment |
up vote
1
down vote
As @Ruakh says in a comment, the precise timings produced by leetcode are subject to a certain amount of randomness, so they should be taken with a grain of salt:
My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors.
Still, it is possible to speed your first loop up quite a bit by getting rid of the tests. The following loop is functionally equivalent; although it sets the variables more often, changing the value of a local integer variable costs less than testing whether it is necessary to change:
for (char c : chars) {
int mask = 1 << c - 'a';
secondSpot |= mask & firstSpot;
firstSpot |= mask;
}
(It's important that the assignment be in that order, so that the first one does nothing if the character hasn't yet been seen.)
add a comment |
up vote
1
down vote
As @Ruakh says in a comment, the precise timings produced by leetcode are subject to a certain amount of randomness, so they should be taken with a grain of salt:
My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors.
Still, it is possible to speed your first loop up quite a bit by getting rid of the tests. The following loop is functionally equivalent; although it sets the variables more often, changing the value of a local integer variable costs less than testing whether it is necessary to change:
for (char c : chars) {
int mask = 1 << c - 'a';
secondSpot |= mask & firstSpot;
firstSpot |= mask;
}
(It's important that the assignment be in that order, so that the first one does nothing if the character hasn't yet been seen.)
add a comment |
up vote
1
down vote
up vote
1
down vote
As @Ruakh says in a comment, the precise timings produced by leetcode are subject to a certain amount of randomness, so they should be taken with a grain of salt:
My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors.
Still, it is possible to speed your first loop up quite a bit by getting rid of the tests. The following loop is functionally equivalent; although it sets the variables more often, changing the value of a local integer variable costs less than testing whether it is necessary to change:
for (char c : chars) {
int mask = 1 << c - 'a';
secondSpot |= mask & firstSpot;
firstSpot |= mask;
}
(It's important that the assignment be in that order, so that the first one does nothing if the character hasn't yet been seen.)
As @Ruakh says in a comment, the precise timings produced by leetcode are subject to a certain amount of randomness, so they should be taken with a grain of salt:
My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors.
Still, it is possible to speed your first loop up quite a bit by getting rid of the tests. The following loop is functionally equivalent; although it sets the variables more often, changing the value of a local integer variable costs less than testing whether it is necessary to change:
for (char c : chars) {
int mask = 1 << c - 'a';
secondSpot |= mask & firstSpot;
firstSpot |= mask;
}
(It's important that the assignment be in that order, so that the first one does nothing if the character hasn't yet been seen.)
answered Nov 20 at 14:34
rici
150k19129194
150k19129194
add a comment |
add a comment |
up vote
1
down vote
Use this:
import java.util.Arrays;
class Solution {
// 0x60 < 'a' < 'z' < 0x80
private final byte bCounter = new byte[0x80];
private final int iCounter = new int[0x80];
public int firstUniqChar(String s) {
int len = s.length();
if ((len & 0xff) == len) {
Arrays.fill(bCounter, 0x60, 0x80, (byte)-1);
for (int i = 0; i < len; i++)
bCounter[s.charAt(i)]++;
for (int i = 0; i < len; i++)
if (bCounter[s.charAt(i)] == 0)
return i;
} else {
Arrays.fill(iCounter, 0x60, 0x80, -1);
for (int i = 0; i < len; i++)
iCounter[s.charAt(i)]++;
for (int i = 0; i < len; i++)
if (iCounter[s.charAt(i)] == 0)
return i;
}
return -1;
}
}
add a comment |
up vote
1
down vote
Use this:
import java.util.Arrays;
class Solution {
// 0x60 < 'a' < 'z' < 0x80
private final byte bCounter = new byte[0x80];
private final int iCounter = new int[0x80];
public int firstUniqChar(String s) {
int len = s.length();
if ((len & 0xff) == len) {
Arrays.fill(bCounter, 0x60, 0x80, (byte)-1);
for (int i = 0; i < len; i++)
bCounter[s.charAt(i)]++;
for (int i = 0; i < len; i++)
if (bCounter[s.charAt(i)] == 0)
return i;
} else {
Arrays.fill(iCounter, 0x60, 0x80, -1);
for (int i = 0; i < len; i++)
iCounter[s.charAt(i)]++;
for (int i = 0; i < len; i++)
if (iCounter[s.charAt(i)] == 0)
return i;
}
return -1;
}
}
add a comment |
up vote
1
down vote
up vote
1
down vote
Use this:
import java.util.Arrays;
class Solution {
// 0x60 < 'a' < 'z' < 0x80
private final byte bCounter = new byte[0x80];
private final int iCounter = new int[0x80];
public int firstUniqChar(String s) {
int len = s.length();
if ((len & 0xff) == len) {
Arrays.fill(bCounter, 0x60, 0x80, (byte)-1);
for (int i = 0; i < len; i++)
bCounter[s.charAt(i)]++;
for (int i = 0; i < len; i++)
if (bCounter[s.charAt(i)] == 0)
return i;
} else {
Arrays.fill(iCounter, 0x60, 0x80, -1);
for (int i = 0; i < len; i++)
iCounter[s.charAt(i)]++;
for (int i = 0; i < len; i++)
if (iCounter[s.charAt(i)] == 0)
return i;
}
return -1;
}
}
Use this:
import java.util.Arrays;
class Solution {
// 0x60 < 'a' < 'z' < 0x80
private final byte bCounter = new byte[0x80];
private final int iCounter = new int[0x80];
public int firstUniqChar(String s) {
int len = s.length();
if ((len & 0xff) == len) {
Arrays.fill(bCounter, 0x60, 0x80, (byte)-1);
for (int i = 0; i < len; i++)
bCounter[s.charAt(i)]++;
for (int i = 0; i < len; i++)
if (bCounter[s.charAt(i)] == 0)
return i;
} else {
Arrays.fill(iCounter, 0x60, 0x80, -1);
for (int i = 0; i < len; i++)
iCounter[s.charAt(i)]++;
for (int i = 0; i < len; i++)
if (iCounter[s.charAt(i)] == 0)
return i;
}
return -1;
}
}
edited Nov 23 at 7:25
answered Nov 23 at 6:23
John McClane
33812
33812
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53383866%2fhow-to-speed-up-first-unique-character-lookup%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 at 23:03
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 at 23:04
1
Re: "LeetCode says that below code is better than 94.33% solutions": My impression is that LeetCode is doing an unscientific microbenchmark that might depend on random factors (such as the other load on their servers at submission-time). So I'm not sure this figure is meant to be taken very seriously.
– ruakh
Nov 20 at 0:25