How to speed up first unique character lookup
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 |
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
3
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 '18 at 23:03
1
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 '18 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 '18 at 0:25
add a comment |
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 '18 at 23:00
Karol DowbeckiKarol Dowbecki
21.5k93154
21.5k93154
3
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 '18 at 23:03
1
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 '18 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 '18 at 0:25
add a comment |
3
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 '18 at 23:03
1
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 '18 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 '18 at 0:25
3
3
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 '18 at 23:03
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 '18 at 23:03
1
1
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 '18 at 23:04
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 '18 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 '18 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 '18 at 0:25
add a comment |
3 Answers
3
active
oldest
votes
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 '18 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 '18 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 '18 at 2:45
add a comment |
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 |
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 |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 '18 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 '18 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 '18 at 2:45
add a comment |
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 '18 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 '18 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 '18 at 2:45
add a comment |
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 '18 at 0:19
KartikKartik
3,74231435
3,74231435
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 '18 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 '18 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 '18 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 '18 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 '18 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 '18 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 '18 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 '18 at 2:44
@0x499602D2 java equivalent please
– Kartik
Nov 20 '18 at 2:45
@0x499602D2 java equivalent please
– Kartik
Nov 20 '18 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 '18 at 2:45
Right this is Java not C++. Sorry.
– 0x499602D2
Nov 20 '18 at 2:45
add a comment |
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 |
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 |
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 '18 at 14:34
ricirici
155k19135202
155k19135202
add a comment |
add a comment |
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 |
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 |
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 '18 at 7:25
answered Nov 23 '18 at 6:23
John McClaneJohn McClane
1,5612419
1,5612419
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.
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
3
This question is better asked on codereview.stackexchange.com
– Andreas
Nov 19 '18 at 23:03
1
Your post could get a better reception at Code Review site.
– PM 77-1
Nov 19 '18 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 '18 at 0:25