Compare Strings

Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
4
down vote
favorite
You have been given two strings, A and B (of length N each) and Q
queries. The strings contain only 0s and/or 1s.
For every query, you are given an index i. You have to update the
value at index i to 1 in string B and check if B is lexicographically
equal to or larger than A or not. If yes, then print "YES" and if not,
print "NO" (without quotes).
Input format
First line contains two space-separated integers N and Q.
Next line contains the string A.
Next line contains the string B.
Next Q lines contains an integer i (1 - based indexing)
Output Format
For each query, print the desired output in a new line.
Sample Input
5 5
11111
00010
1
2
3
4
5
Sample Output
NO
NO
NO
NO
YES
Explanation
After 1st query: B = 10010. B < A. (NO)
After 2nd query: B = 11010. B < A. (NO)
After 3rd query: B = 11110. B < A. (NO)
After 4th query: B = 11110. B < A. (NO)
After 5th query: B = 11111. B = A. (YES)
My solution in Python:
# Write your code here
N_Q = list(map(int, input().split()))
string_a_list = list(input())
string_b_list = list(input())
different_set = set()
for index in range(N_Q[0]):
if string_a_list[index] != string_b_list[index]:
different_set.add(index + 1)
for query in range(N_Q[1]):
index_q = int(input()) # 1 based
index = index_q - 1
string_b_list[index] = 1
if len(different_set) == 0:
break
if int(string_a_list[index]) == int(string_b_list[index]):
different_set.discard(index_q)
if len(different_set) != 0:
print("NO")
if len(different_set) == 0:
print("YES")
if len(different_set) > 0:
firstIndex = next(iter(different_set))
index == firstIndex - 1
if int(string_a_list[index]) > int(string_b_list[index]):
print("NO")
if int(string_a_list[index]) < int(string_b_list[index]):
print("YES")
But for one test case that has got really very large input it's taking 5 sec so I'm getting timeout for that case:
Submission
Input #8 5.001169 22512 0
How can I optimize this further? What are the critical points to solve problem like this that I'm missing?
python algorithm python-3.x time-limit-exceeded complexity
add a comment |Â
up vote
4
down vote
favorite
You have been given two strings, A and B (of length N each) and Q
queries. The strings contain only 0s and/or 1s.
For every query, you are given an index i. You have to update the
value at index i to 1 in string B and check if B is lexicographically
equal to or larger than A or not. If yes, then print "YES" and if not,
print "NO" (without quotes).
Input format
First line contains two space-separated integers N and Q.
Next line contains the string A.
Next line contains the string B.
Next Q lines contains an integer i (1 - based indexing)
Output Format
For each query, print the desired output in a new line.
Sample Input
5 5
11111
00010
1
2
3
4
5
Sample Output
NO
NO
NO
NO
YES
Explanation
After 1st query: B = 10010. B < A. (NO)
After 2nd query: B = 11010. B < A. (NO)
After 3rd query: B = 11110. B < A. (NO)
After 4th query: B = 11110. B < A. (NO)
After 5th query: B = 11111. B = A. (YES)
My solution in Python:
# Write your code here
N_Q = list(map(int, input().split()))
string_a_list = list(input())
string_b_list = list(input())
different_set = set()
for index in range(N_Q[0]):
if string_a_list[index] != string_b_list[index]:
different_set.add(index + 1)
for query in range(N_Q[1]):
index_q = int(input()) # 1 based
index = index_q - 1
string_b_list[index] = 1
if len(different_set) == 0:
break
if int(string_a_list[index]) == int(string_b_list[index]):
different_set.discard(index_q)
if len(different_set) != 0:
print("NO")
if len(different_set) == 0:
print("YES")
if len(different_set) > 0:
firstIndex = next(iter(different_set))
index == firstIndex - 1
if int(string_a_list[index]) > int(string_b_list[index]):
print("NO")
if int(string_a_list[index]) < int(string_b_list[index]):
print("YES")
But for one test case that has got really very large input it's taking 5 sec so I'm getting timeout for that case:
Submission
Input #8 5.001169 22512 0
How can I optimize this further? What are the critical points to solve problem like this that I'm missing?
python algorithm python-3.x time-limit-exceeded complexity
add a comment |Â
up vote
4
down vote
favorite
up vote
4
down vote
favorite
You have been given two strings, A and B (of length N each) and Q
queries. The strings contain only 0s and/or 1s.
For every query, you are given an index i. You have to update the
value at index i to 1 in string B and check if B is lexicographically
equal to or larger than A or not. If yes, then print "YES" and if not,
print "NO" (without quotes).
Input format
First line contains two space-separated integers N and Q.
Next line contains the string A.
Next line contains the string B.
Next Q lines contains an integer i (1 - based indexing)
Output Format
For each query, print the desired output in a new line.
Sample Input
5 5
11111
00010
1
2
3
4
5
Sample Output
NO
NO
NO
NO
YES
Explanation
After 1st query: B = 10010. B < A. (NO)
After 2nd query: B = 11010. B < A. (NO)
After 3rd query: B = 11110. B < A. (NO)
After 4th query: B = 11110. B < A. (NO)
After 5th query: B = 11111. B = A. (YES)
My solution in Python:
# Write your code here
N_Q = list(map(int, input().split()))
string_a_list = list(input())
string_b_list = list(input())
different_set = set()
for index in range(N_Q[0]):
if string_a_list[index] != string_b_list[index]:
different_set.add(index + 1)
for query in range(N_Q[1]):
index_q = int(input()) # 1 based
index = index_q - 1
string_b_list[index] = 1
if len(different_set) == 0:
break
if int(string_a_list[index]) == int(string_b_list[index]):
different_set.discard(index_q)
if len(different_set) != 0:
print("NO")
if len(different_set) == 0:
print("YES")
if len(different_set) > 0:
firstIndex = next(iter(different_set))
index == firstIndex - 1
if int(string_a_list[index]) > int(string_b_list[index]):
print("NO")
if int(string_a_list[index]) < int(string_b_list[index]):
print("YES")
But for one test case that has got really very large input it's taking 5 sec so I'm getting timeout for that case:
Submission
Input #8 5.001169 22512 0
How can I optimize this further? What are the critical points to solve problem like this that I'm missing?
python algorithm python-3.x time-limit-exceeded complexity
You have been given two strings, A and B (of length N each) and Q
queries. The strings contain only 0s and/or 1s.
For every query, you are given an index i. You have to update the
value at index i to 1 in string B and check if B is lexicographically
equal to or larger than A or not. If yes, then print "YES" and if not,
print "NO" (without quotes).
Input format
First line contains two space-separated integers N and Q.
Next line contains the string A.
Next line contains the string B.
Next Q lines contains an integer i (1 - based indexing)
Output Format
For each query, print the desired output in a new line.
Sample Input
5 5
11111
00010
1
2
3
4
5
Sample Output
NO
NO
NO
NO
YES
Explanation
After 1st query: B = 10010. B < A. (NO)
After 2nd query: B = 11010. B < A. (NO)
After 3rd query: B = 11110. B < A. (NO)
After 4th query: B = 11110. B < A. (NO)
After 5th query: B = 11111. B = A. (YES)
My solution in Python:
# Write your code here
N_Q = list(map(int, input().split()))
string_a_list = list(input())
string_b_list = list(input())
different_set = set()
for index in range(N_Q[0]):
if string_a_list[index] != string_b_list[index]:
different_set.add(index + 1)
for query in range(N_Q[1]):
index_q = int(input()) # 1 based
index = index_q - 1
string_b_list[index] = 1
if len(different_set) == 0:
break
if int(string_a_list[index]) == int(string_b_list[index]):
different_set.discard(index_q)
if len(different_set) != 0:
print("NO")
if len(different_set) == 0:
print("YES")
if len(different_set) > 0:
firstIndex = next(iter(different_set))
index == firstIndex - 1
if int(string_a_list[index]) > int(string_b_list[index]):
print("NO")
if int(string_a_list[index]) < int(string_b_list[index]):
print("YES")
But for one test case that has got really very large input it's taking 5 sec so I'm getting timeout for that case:
Submission
Input #8 5.001169 22512 0
How can I optimize this further? What are the critical points to solve problem like this that I'm missing?
python algorithm python-3.x time-limit-exceeded complexity
edited May 13 at 21:53
Jamalâ¦
30.1k11114225
30.1k11114225
asked May 12 at 11:39
Ankur Anand
3811614
3811614
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
1
down vote
One way to solve this is to keep a track of lexicographical ordering for every pair of suffixes. Then for every update just update the ordering for suffix starting from index i. If ordering was changed then update suffix starting from i-1 and keep on updating as long as there are changes. The current state after every query can be found from suffix[0].
n, q = (int(x) for x in input().split())
a = [int(x) for x in input()]
b = [int(x) for x in input()]
def update(idx):
for i in range(idx, -1, -1):
x = b[i] - a[i]
if x == 0 and i < n - 1:
x = suffix[i + 1]
if x == suffix[i]:
break
suffix[i] = x
# Initialize to invalid value to force initial update
suffix = [-2] * n
update(n - 1)
# Buffer results for faster output
res =
for _ in range(q):
i = int(input()) - 1
b[i] = 1
update(i)
res.append('YES' if suffix[0] >= 0 else 'NO')
print('n'.join(res))
Since every index can be updated maximum 2 times the time complexity is O(N + Q).
add a comment |Â
up vote
1
down vote
You can
- List item
- just use list comparison, so no need to convert between int and str
- make a and b lists of 1s and 0s
- make the diff-set with a set comparison
- keep a flag. Once b is larger than or equal to a, it will stay this way
My code:
N, Q = list(map(int, input().split()))
a = list(map(int, input()))
b = list(map(int, input()))
diff = i
for i, (j, k) in enumerate(zip(a, b))
if j != k
smaller = a > b
for _ in range(Q):
idx = int(input()) - 1
if smaller and idx in diff:
b[idx] = 1
diff.remove(idx)
if smaller and a > b :
print('NO')
else:
print('YES')
smaller = True
else:
if smaller:
print('NO')
else:
print('YES')
smaller = False
Alternative solution
What really matters is at what index the first element of A is larger than B and vice versa, so we just keep track of those, and only set B[idx] to 1 in :
N, Q = list(map(int, input().split()))
A = list(map(int, input()))
B = list(map(int, input()))
idx_a = None
idx_b = len(B)
for i, (a, b) in enumerate(zip(A, B)):
if a > b and idx_a is None:
idx_a = i
if idx_a is not None and b > a:
idx_b = i
break
a_larger = True
if idx_a is None:
a_larger = False
for _ in range(Q):
idx = int(input()) - 1
if not a_larger:
print('YES')
continue
elif idx < idx_a:
if not B[idx]:
print('YES')
a_larger = False
else:
print('NO')
continue
elif idx == idx_a:
B[idx] = 1
idx_a = find_new_a_idx(A, B, idx_a, idx_b)
if idx_a is None:
print('YES')
a_larger = False
else:
print('NO')
continue
print('NO')
if idx >= idx_b:
continue
if not B[idx]:
B[idx] = 1
if not A[idx]:
idx_b = idx
This is rather ugly code to take all the edge cases into account.
I tried also with array.array('b)', but that was not faster
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
One way to solve this is to keep a track of lexicographical ordering for every pair of suffixes. Then for every update just update the ordering for suffix starting from index i. If ordering was changed then update suffix starting from i-1 and keep on updating as long as there are changes. The current state after every query can be found from suffix[0].
n, q = (int(x) for x in input().split())
a = [int(x) for x in input()]
b = [int(x) for x in input()]
def update(idx):
for i in range(idx, -1, -1):
x = b[i] - a[i]
if x == 0 and i < n - 1:
x = suffix[i + 1]
if x == suffix[i]:
break
suffix[i] = x
# Initialize to invalid value to force initial update
suffix = [-2] * n
update(n - 1)
# Buffer results for faster output
res =
for _ in range(q):
i = int(input()) - 1
b[i] = 1
update(i)
res.append('YES' if suffix[0] >= 0 else 'NO')
print('n'.join(res))
Since every index can be updated maximum 2 times the time complexity is O(N + Q).
add a comment |Â
up vote
1
down vote
One way to solve this is to keep a track of lexicographical ordering for every pair of suffixes. Then for every update just update the ordering for suffix starting from index i. If ordering was changed then update suffix starting from i-1 and keep on updating as long as there are changes. The current state after every query can be found from suffix[0].
n, q = (int(x) for x in input().split())
a = [int(x) for x in input()]
b = [int(x) for x in input()]
def update(idx):
for i in range(idx, -1, -1):
x = b[i] - a[i]
if x == 0 and i < n - 1:
x = suffix[i + 1]
if x == suffix[i]:
break
suffix[i] = x
# Initialize to invalid value to force initial update
suffix = [-2] * n
update(n - 1)
# Buffer results for faster output
res =
for _ in range(q):
i = int(input()) - 1
b[i] = 1
update(i)
res.append('YES' if suffix[0] >= 0 else 'NO')
print('n'.join(res))
Since every index can be updated maximum 2 times the time complexity is O(N + Q).
add a comment |Â
up vote
1
down vote
up vote
1
down vote
One way to solve this is to keep a track of lexicographical ordering for every pair of suffixes. Then for every update just update the ordering for suffix starting from index i. If ordering was changed then update suffix starting from i-1 and keep on updating as long as there are changes. The current state after every query can be found from suffix[0].
n, q = (int(x) for x in input().split())
a = [int(x) for x in input()]
b = [int(x) for x in input()]
def update(idx):
for i in range(idx, -1, -1):
x = b[i] - a[i]
if x == 0 and i < n - 1:
x = suffix[i + 1]
if x == suffix[i]:
break
suffix[i] = x
# Initialize to invalid value to force initial update
suffix = [-2] * n
update(n - 1)
# Buffer results for faster output
res =
for _ in range(q):
i = int(input()) - 1
b[i] = 1
update(i)
res.append('YES' if suffix[0] >= 0 else 'NO')
print('n'.join(res))
Since every index can be updated maximum 2 times the time complexity is O(N + Q).
One way to solve this is to keep a track of lexicographical ordering for every pair of suffixes. Then for every update just update the ordering for suffix starting from index i. If ordering was changed then update suffix starting from i-1 and keep on updating as long as there are changes. The current state after every query can be found from suffix[0].
n, q = (int(x) for x in input().split())
a = [int(x) for x in input()]
b = [int(x) for x in input()]
def update(idx):
for i in range(idx, -1, -1):
x = b[i] - a[i]
if x == 0 and i < n - 1:
x = suffix[i + 1]
if x == suffix[i]:
break
suffix[i] = x
# Initialize to invalid value to force initial update
suffix = [-2] * n
update(n - 1)
# Buffer results for faster output
res =
for _ in range(q):
i = int(input()) - 1
b[i] = 1
update(i)
res.append('YES' if suffix[0] >= 0 else 'NO')
print('n'.join(res))
Since every index can be updated maximum 2 times the time complexity is O(N + Q).
edited May 16 at 6:22
answered May 16 at 6:13
niemmi
1664
1664
add a comment |Â
add a comment |Â
up vote
1
down vote
You can
- List item
- just use list comparison, so no need to convert between int and str
- make a and b lists of 1s and 0s
- make the diff-set with a set comparison
- keep a flag. Once b is larger than or equal to a, it will stay this way
My code:
N, Q = list(map(int, input().split()))
a = list(map(int, input()))
b = list(map(int, input()))
diff = i
for i, (j, k) in enumerate(zip(a, b))
if j != k
smaller = a > b
for _ in range(Q):
idx = int(input()) - 1
if smaller and idx in diff:
b[idx] = 1
diff.remove(idx)
if smaller and a > b :
print('NO')
else:
print('YES')
smaller = True
else:
if smaller:
print('NO')
else:
print('YES')
smaller = False
Alternative solution
What really matters is at what index the first element of A is larger than B and vice versa, so we just keep track of those, and only set B[idx] to 1 in :
N, Q = list(map(int, input().split()))
A = list(map(int, input()))
B = list(map(int, input()))
idx_a = None
idx_b = len(B)
for i, (a, b) in enumerate(zip(A, B)):
if a > b and idx_a is None:
idx_a = i
if idx_a is not None and b > a:
idx_b = i
break
a_larger = True
if idx_a is None:
a_larger = False
for _ in range(Q):
idx = int(input()) - 1
if not a_larger:
print('YES')
continue
elif idx < idx_a:
if not B[idx]:
print('YES')
a_larger = False
else:
print('NO')
continue
elif idx == idx_a:
B[idx] = 1
idx_a = find_new_a_idx(A, B, idx_a, idx_b)
if idx_a is None:
print('YES')
a_larger = False
else:
print('NO')
continue
print('NO')
if idx >= idx_b:
continue
if not B[idx]:
B[idx] = 1
if not A[idx]:
idx_b = idx
This is rather ugly code to take all the edge cases into account.
I tried also with array.array('b)', but that was not faster
add a comment |Â
up vote
1
down vote
You can
- List item
- just use list comparison, so no need to convert between int and str
- make a and b lists of 1s and 0s
- make the diff-set with a set comparison
- keep a flag. Once b is larger than or equal to a, it will stay this way
My code:
N, Q = list(map(int, input().split()))
a = list(map(int, input()))
b = list(map(int, input()))
diff = i
for i, (j, k) in enumerate(zip(a, b))
if j != k
smaller = a > b
for _ in range(Q):
idx = int(input()) - 1
if smaller and idx in diff:
b[idx] = 1
diff.remove(idx)
if smaller and a > b :
print('NO')
else:
print('YES')
smaller = True
else:
if smaller:
print('NO')
else:
print('YES')
smaller = False
Alternative solution
What really matters is at what index the first element of A is larger than B and vice versa, so we just keep track of those, and only set B[idx] to 1 in :
N, Q = list(map(int, input().split()))
A = list(map(int, input()))
B = list(map(int, input()))
idx_a = None
idx_b = len(B)
for i, (a, b) in enumerate(zip(A, B)):
if a > b and idx_a is None:
idx_a = i
if idx_a is not None and b > a:
idx_b = i
break
a_larger = True
if idx_a is None:
a_larger = False
for _ in range(Q):
idx = int(input()) - 1
if not a_larger:
print('YES')
continue
elif idx < idx_a:
if not B[idx]:
print('YES')
a_larger = False
else:
print('NO')
continue
elif idx == idx_a:
B[idx] = 1
idx_a = find_new_a_idx(A, B, idx_a, idx_b)
if idx_a is None:
print('YES')
a_larger = False
else:
print('NO')
continue
print('NO')
if idx >= idx_b:
continue
if not B[idx]:
B[idx] = 1
if not A[idx]:
idx_b = idx
This is rather ugly code to take all the edge cases into account.
I tried also with array.array('b)', but that was not faster
add a comment |Â
up vote
1
down vote
up vote
1
down vote
You can
- List item
- just use list comparison, so no need to convert between int and str
- make a and b lists of 1s and 0s
- make the diff-set with a set comparison
- keep a flag. Once b is larger than or equal to a, it will stay this way
My code:
N, Q = list(map(int, input().split()))
a = list(map(int, input()))
b = list(map(int, input()))
diff = i
for i, (j, k) in enumerate(zip(a, b))
if j != k
smaller = a > b
for _ in range(Q):
idx = int(input()) - 1
if smaller and idx in diff:
b[idx] = 1
diff.remove(idx)
if smaller and a > b :
print('NO')
else:
print('YES')
smaller = True
else:
if smaller:
print('NO')
else:
print('YES')
smaller = False
Alternative solution
What really matters is at what index the first element of A is larger than B and vice versa, so we just keep track of those, and only set B[idx] to 1 in :
N, Q = list(map(int, input().split()))
A = list(map(int, input()))
B = list(map(int, input()))
idx_a = None
idx_b = len(B)
for i, (a, b) in enumerate(zip(A, B)):
if a > b and idx_a is None:
idx_a = i
if idx_a is not None and b > a:
idx_b = i
break
a_larger = True
if idx_a is None:
a_larger = False
for _ in range(Q):
idx = int(input()) - 1
if not a_larger:
print('YES')
continue
elif idx < idx_a:
if not B[idx]:
print('YES')
a_larger = False
else:
print('NO')
continue
elif idx == idx_a:
B[idx] = 1
idx_a = find_new_a_idx(A, B, idx_a, idx_b)
if idx_a is None:
print('YES')
a_larger = False
else:
print('NO')
continue
print('NO')
if idx >= idx_b:
continue
if not B[idx]:
B[idx] = 1
if not A[idx]:
idx_b = idx
This is rather ugly code to take all the edge cases into account.
I tried also with array.array('b)', but that was not faster
You can
- List item
- just use list comparison, so no need to convert between int and str
- make a and b lists of 1s and 0s
- make the diff-set with a set comparison
- keep a flag. Once b is larger than or equal to a, it will stay this way
My code:
N, Q = list(map(int, input().split()))
a = list(map(int, input()))
b = list(map(int, input()))
diff = i
for i, (j, k) in enumerate(zip(a, b))
if j != k
smaller = a > b
for _ in range(Q):
idx = int(input()) - 1
if smaller and idx in diff:
b[idx] = 1
diff.remove(idx)
if smaller and a > b :
print('NO')
else:
print('YES')
smaller = True
else:
if smaller:
print('NO')
else:
print('YES')
smaller = False
Alternative solution
What really matters is at what index the first element of A is larger than B and vice versa, so we just keep track of those, and only set B[idx] to 1 in :
N, Q = list(map(int, input().split()))
A = list(map(int, input()))
B = list(map(int, input()))
idx_a = None
idx_b = len(B)
for i, (a, b) in enumerate(zip(A, B)):
if a > b and idx_a is None:
idx_a = i
if idx_a is not None and b > a:
idx_b = i
break
a_larger = True
if idx_a is None:
a_larger = False
for _ in range(Q):
idx = int(input()) - 1
if not a_larger:
print('YES')
continue
elif idx < idx_a:
if not B[idx]:
print('YES')
a_larger = False
else:
print('NO')
continue
elif idx == idx_a:
B[idx] = 1
idx_a = find_new_a_idx(A, B, idx_a, idx_b)
if idx_a is None:
print('YES')
a_larger = False
else:
print('NO')
continue
print('NO')
if idx >= idx_b:
continue
if not B[idx]:
B[idx] = 1
if not A[idx]:
idx_b = idx
This is rather ugly code to take all the edge cases into account.
I tried also with array.array('b)', but that was not faster
edited May 16 at 6:48
greybeard
1,3231521
1,3231521
answered May 12 at 12:24
Maarten Fabré
3,204214
3,204214
add a comment |Â
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f194250%2fcompare-strings%23new-answer', 'question_page');
);
Post as a guest
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
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
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