Skip to content

Commit e45cf8f

Browse files
committed
add
1 parent 0dc4c62 commit e45cf8f

11 files changed

+565
-0
lines changed

1001 Grid Illumination.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/python3
2+
"""
3+
4+
"""
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/python3
2+
"""
3+
Given a string s, determine if it is valid.
4+
5+
A string s is valid if, starting with an empty string t = "", you can transform t into s after performing the following operation any number of times:
6+
7+
Insert string "abc" into any position in t. More formally, t becomes tleft + "abc" + tright, where t == tleft + tright. Note that tleft and tright may be empty.
8+
Return true if s is a valid string, otherwise, return false.
9+
10+
11+
12+
Example 1:
13+
14+
Input: s = "aabcbc"
15+
Output: true
16+
Explanation:
17+
"" -> "abc" -> "aabcbc"
18+
Thus, "aabcbc" is valid.
19+
Example 2:
20+
21+
Input: s = "abcabcababcc"
22+
Output: true
23+
Explanation:
24+
"" -> "abc" -> "abcabc" -> "abcabcabc" -> "abcabcababcc"
25+
Thus, "abcabcababcc" is valid.
26+
Example 3:
27+
28+
Input: s = "abccba"
29+
Output: false
30+
Explanation: It is impossible to get "abccba" using the operation.
31+
32+
33+
Constraints:
34+
35+
1 <= s.length <= 2 * 104
36+
s consists of letters 'a', 'b', and 'c'
37+
"""
38+
39+
from collections import defaultdict
40+
41+
class Solution:
42+
def isValid_naive(self, s: str) -> bool:
43+
"""
44+
similar to valid parenthesis of ()
45+
cnt[a] >= cnt[b] >= cnt[c]
46+
in the end, cnt[a] == cnt[b] == cnt[c]
47+
but aaabbbccc is invalid
48+
49+
remove "abc", there another "abc" in the string. O(N^2)
50+
"""
51+
if len(s) == 0:
52+
return True
53+
54+
for i in range(len(s) - 2):
55+
if s[i:i+3] == "abc":
56+
return self.isValid(s[:i] + s[i+3:])
57+
58+
return False
59+
60+
def isValid(self, s: str) -> bool:
61+
"""
62+
when c, we there must be a and b immediately before
63+
using stk
64+
"""
65+
stk = []
66+
for e in s:
67+
if e in ("a", "b"):
68+
stk.append(e)
69+
else: # "c"
70+
if len(stk) < 2:
71+
return False
72+
if stk.pop() != "b":
73+
return False
74+
if stk.pop() != "a":
75+
return False
76+
77+
return len(stk) == 0

1006 Clumsy Factorial.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/python3
2+
"""
3+
The factorial of a positive integer n is the product of all positive integers less than or equal to n.
4+
5+
For example, factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1.
6+
We make a clumsy factorial using the integers in decreasing order by swapping out the multiply operations for a fixed rotation of operations with multiply '*', divide '/', add '+', and subtract '-' in this order.
7+
8+
For example, clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1.
9+
However, these operations are still applied using the usual order of operations of arithmetic. We do all multiplication and division steps before any addition or subtraction steps, and multiplication and division steps are processed left to right.
10+
11+
Additionally, the division that we use is floor division such that 10 * 9 / 8 = 90 / 8 = 11.
12+
13+
Given an integer n, return the clumsy factorial of n.
14+
15+
16+
17+
Example 1:
18+
19+
Input: n = 4
20+
Output: 7
21+
Explanation: 7 = 4 * 3 / 2 + 1
22+
Example 2:
23+
24+
Input: n = 10
25+
Output: 12
26+
Explanation: 12 = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1
27+
28+
29+
Constraints:
30+
31+
1 <= n <= 104
32+
"""
33+
34+
class Solution:
35+
def clumsy(self, n: int) -> int:
36+
"""
37+
* / + -
38+
+ is applied,
39+
- the next set of * /
40+
"""
41+
accu = 0
42+
for i in range(min(4, n)):
43+
num = n - i
44+
if i % 4 == 0:
45+
accu += num
46+
elif i % 4 == 1:
47+
accu *= num
48+
elif i % 4 == 2:
49+
accu //= num
50+
else:
51+
accu += num
52+
53+
cur = 0
54+
for i in range(4, n):
55+
num = n - i
56+
if i % 4 == 0:
57+
cur += num
58+
elif i % 4 == 1:
59+
cur *= num
60+
elif i % 4 == 2:
61+
cur //= num
62+
else:
63+
accu += num
64+
accu -= cur
65+
cur = 0
66+
67+
return accu - cur # remaining cur
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/python3
2+
"""
3+
In a row of dominoes, tops[i] and bottoms[i] represent the top and bottom halves of the ith domino. (A domino is a tile with two numbers from 1 to 6 - one on each half of the tile.)
4+
5+
We may rotate the ith domino, so that tops[i] and bottoms[i] swap values.
6+
7+
Return the minimum number of rotations so that all the values in tops are the same, or all the values in bottoms are the same.
8+
9+
If it cannot be done, return -1.
10+
11+
12+
Example 1:
13+
14+
15+
Input: tops = [2,1,2,4,2,2], bottoms = [5,2,6,2,3,2]
16+
Output: 2
17+
Explanation:
18+
The first figure represents the dominoes as given by tops and bottoms: before we do any rotations.
19+
If we rotate the second and fourth dominoes, we can make every value in the top row equal to 2, as indicated by the second figure.
20+
Example 2:
21+
22+
Input: tops = [3,5,1,2,3], bottoms = [3,6,3,3,4]
23+
Output: -1
24+
Explanation:
25+
In this case, it is not possible to rotate the dominoes to make one row of values equal.
26+
27+
28+
Constraints:
29+
30+
2 <= tops.length <= 2 * 104
31+
bottoms.length == tops.length
32+
1 <= tops[i], bottoms[i] <= 6
33+
"""
34+
class Solution:
35+
def minDominoRotations(self, tops: List[int], bottoms: List[int]) -> int:
36+
"""
37+
Mainly focus on making tops the same
38+
bottoms check can be done by swapping the params
39+
40+
find target first and then swap
41+
"""
42+
return min(self.find_min(tops, bottoms), self.find_min(bottoms, tops))
43+
44+
def find_min(self, tops, bottoms):
45+
targets = set([tops[0], bottoms[0]])
46+
N = len(tops)
47+
for i in range(1, N):
48+
targets &= set([tops[i], bottoms[i]])
49+
50+
if len(targets) == 0:
51+
return -1
52+
53+
target = targets.pop()
54+
swap = 0
55+
for i in range(N):
56+
if target != tops[i]:
57+
swap += 1
58+
59+
return swap
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/python3
2+
"""
3+
Given a positive integer k, you need to find the length of the smallest positive integer n such that n is divisible by k, and n only contains the digit 1.
4+
5+
Return the length of n. If there is no such n, return -1.
6+
7+
Note: n may not fit in a 64-bit signed integer.
8+
9+
10+
11+
Example 1:
12+
13+
Input: k = 1
14+
Output: 1
15+
Explanation: The smallest answer is n = 1, which has length 1.
16+
Example 2:
17+
18+
Input: k = 2
19+
Output: -1
20+
Explanation: There is no such positive integer n divisible by 2.
21+
Example 3:
22+
23+
Input: k = 3
24+
Output: 3
25+
Explanation: The smallest answer is n = 111, which has length 3.
26+
27+
28+
Constraints:
29+
30+
1 <= k <= 10^5
31+
"""
32+
from collections import defaultdict
33+
34+
35+
class Solution:
36+
def smallestRepunitDivByK(self, k: int) -> int:
37+
"""
38+
1 % k = 1
39+
11 % k = prev * 10 + 1 % k
40+
111 % k = prev * 10 + 1 % k
41+
"""
42+
if k % 2 == 0 or k % 5 == 0:
43+
return -1
44+
45+
hit = defaultdict(bool)
46+
l = 1
47+
cur = 1
48+
remainder = 1 % k
49+
while True:
50+
if hit[remainder]:
51+
return -1
52+
if remainder == 0:
53+
return l
54+
55+
hit[remainder] = True
56+
remainder = (remainder * 10 + 1) % k
57+
l += 1
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/python3
2+
"""
3+
Given a binary string s and a positive integer n, return true if the binary representation of all the integers in the range [1, n] are substrings of s, or false otherwise.
4+
5+
A substring is a contiguous sequence of characters within a string.
6+
7+
Example 1:
8+
9+
Input: s = "0110", n = 3
10+
Output: true
11+
Example 2:
12+
13+
Input: s = "0110", n = 4
14+
Output: false
15+
16+
17+
Constraints:
18+
19+
1 <= s.length <= 1000
20+
s[i] is either '0' or '1'.
21+
1 <= n <= 10^9
22+
"""
23+
24+
class Solution:
25+
def queryString(self, s: str, n: int) -> bool:
26+
"""
27+
Naive solution: KMP string matching from 1 to N, O(N * (m + n)).
28+
Python `in` is enough
29+
30+
Construct numbers from the string s itself
31+
Scan the s from left to right
32+
"""
33+
numbers = set()
34+
for i in range(len(s)):
35+
cur = 0
36+
sig = 1
37+
for j in range(i, len(s)):
38+
if s[~j] == "1":
39+
cur += sig
40+
if cur > n:
41+
break
42+
43+
sig <<= 1
44+
45+
if cur != 0:
46+
numbers.add(cur)
47+
48+
return len(numbers) == n

0 commit comments

Comments
 (0)