All Medium Problems
All Medium Problems
top-k-frequent-elements.py 12
reconstruct-original-digits-from-english.py 15
compare-version-numbers.py 16
combination-sum-iv.py 19
koko-eating-bananas.py 20
random-pick-with-weight.py 21
find-k-closest-elements.py 23
jump-game-iii.py 24
single-number-ii.py 26
array-of-doubled-pairs.py 28
jump-game.py 29
remove-k-digits.py 30
construct-quad-tree.py 31
search-in-rotated-sorted-array-ii.py 34
delete-operation-for-two-strings.py 35
length-of-longest-fibonacci-subsequence.py 37
bitwise-ors-of-subarrays.py 39
check-completeness-of-a-binary-tree.py 40
increasing-subsequences.py 42
binary-string-with-substrings-representing-1-to-n.py 43
valid-parenthesis-string.py 44
total-hamming-distance.py 45
serialize-and-deserialize-bst.py 46
product-of-array-except-self.py 48
queue-reconstruction-by-height.py 49
building-h2o.py 50
next-greater-element-ii.py 53
rotate-image.py 54
surrounded-regions.py 56
magical-string.py 58
split-array-into-consecutive-subsequences.py 60
beautiful-array.py 62
1
path-sum-iii.py 63
design-underground-system.py 65
find-all-duplicates-in-an-array.py 68
zigzag-conversion.py 70
number-of-dice-rolls-with-target-sum.py 71
knight-dialer.py 73
maximum-difference-between-node-and-ancestor.py 76
maximum-product-of-word-lengths.py 78
remove-duplicates-from-sorted-list-ii.py 80
longest-arithmetic-subsequence-of-given-difference.py 81
sum-of-two-integers.py 82
partition-equal-subset-sum.py 84
moving-stones-until-consecutive-ii.py 85
corporate-flight-bookings.py 86
print-binary-tree.py 87
linked-list-random-node.py 89
swap-for-longest-repeated-character-substring.py 90
maximum-sum-of-two-non-overlapping-subarrays.py 92
binary-tree-level-order-traversal.py 93
construct-binary-search-tree-from-preorder-traversal.py 94
minimum-number-of-arrows-to-burst-balloons.py 95
search-a-2d-matrix-ii.py 96
mini-parser.py 97
angle-between-hands-of-a-clock.py 99
out-of-boundary-paths.py 101
battleships-in-a-board.py 102
subarray-sum-equals-k.py 103
set-matrix-zeroes.py 104
best-sightseeing-pair.py 106
find-k-pairs-with-smallest-sums.py 107
distribute-coins-in-binary-tree.py 109
sort-characters-by-frequency.py 111
minimum-area-rectangle.py 113
2
sequential-digits.py 115
perfect-squares.py 116
longest-turbulent-subarray.py 117
next-greater-node-in-linked-list.py 118
friend-circles.py 119
score-of-parentheses.py 121
beautiful-arrangement-ii.py 123
matrix-block-sum.py 124
maximum-of-absolute-value-expression.py 125
single-element-in-a-sorted-array.py 127
group-anagrams.py 128
uncrossed-lines.py 129
partition-list.py 131
filling-bookcase-shelves.py 132
sum-of-mutated-array-closest-to-target.py 134
2-keys-keyboard.py 136
binary-search-tree-iterator.py 137
find-the-duplicate-number.py 139
merge-intervals.py 141
largest-values-from-labels.py 142
3sum-closest.py 144
solve-the-equation.py 145
minimum-height-trees.py 147
continuous-subarray-sum.py 149
brick-wall.py 150
gray-code.py 152
odd-even-linked-list.py 153
basic-calculator-ii.py 156
populating-next-right-pointers-in-each-node-ii.py 158
all-elements-in-two-binary-search-trees.py 160
search-a-2d-matrix.py 162
find-all-anagrams-in-a-string.py 163
fizz-buzz-multithreaded.py 164
3
minimum-genetic-mutation.py 166
alphabet-board-path.py 168
pancake-sorting.py 170
01-matrix.py 172
maximum-product-subarray.py 174
distant-barcodes.py 175
binary-subarrays-with-sum.py 176
delete-node-in-a-bst.py 177
random-pick-index.py 179
word-break.py 180
video-stitching.py 181
shortest-path-with-alternating-colors.py 183
maximum-width-ramp.py 185
binary-search-tree-to-greater-sum-tree.py 186
nth-digit.py 187
elimination-game.py 188
can-make-palindrome-from-substring.py 189
design-twitter.py 191
palindrome-partitioning.py 193
rectangle-area.py 195
course-schedule-ii.py 196
car-pooling.py 198
maximum-nesting-depth-of-two-valid-parentheses-strings.py 199
maximum-level-sum-of-a-binary-tree.py 201
combination-sum.py 203
flip-string-to-monotone-increasing.py 205
grumpy-bookstore-owner.py 206
lowest-common-ancestor-of-a-binary-tree.py 207
spiral-matrix-iii.py 208
robot-bounded-in-circle.py 209
super-pow.py 211
find-duplicate-subtrees.py 212
insertion-sort-list.py 214
4
mirror-reflection.py 216
reverse-linked-list-ii.py 217
validate-binary-tree-nodes.py 218
unique-paths-ii.py 220
longest-absolute-file-path.py 221
vowel-spellchecker.py 223
shuffle-an-array.py 225
minimum-falling-path-sum.py 226
boats-to-save-people.py 227
sum-root-to-leaf-numbers.py 228
different-ways-to-add-parentheses.py 229
as-far-from-land-as-possible.py 231
broken-calculator.py 233
construct-binary-tree-from-preorder-and-inorder-traversal.py 235
longest-palindromic-substring.py 237
replace-words.py 238
k-concatenation-maximum-sum.py 240
ones-and-zeroes.py 241
validate-binary-search-tree.py 242
decoded-string-at-index.py 244
rotate-list.py 246
minimum-path-sum.py 247
spiral-matrix-ii.py 248
palindromic-substrings.py 249
numbers-with-same-consecutive-differences.py 250
longest-well-performing-interval.py 251
add-two-numbers-ii.py 252
minimum-area-rectangle-ii.py 253
clumsy-factorial.py 254
next-greater-element-iii.py 256
permutations.py 257
number-of-longest-increasing-subsequence.py 259
shortest-bridge.py 260
5
complex-number-multiplication.py 262
copy-list-with-random-pointer.py 263
container-with-most-water.py 266
find-duplicate-file-in-system.py 267
fraction-to-recurring-decimal.py 269
path-with-maximum-probability.py 270
house-robber-iii.py 272
letter-tile-possibilities.py 273
sort-an-array.py 275
the-dining-philosophers.py 277
majority-element-ii.py 279
reordered-power-of-2.py 281
smallest-string-starting-from-leaf.py 282
delete-nodes-and-return-forest.py 284
flip-columns-for-maximum-number-of-equal-rows.py 285
advantage-shuffle.py 286
string-without-aaa-or-bbb.py 287
populating-next-right-pointers-in-each-node.py 288
sum-of-nodes-with-even-valued-grandparent.py 290
print-zero-even-odd.py 291
matchsticks-to-square.py 293
remove-zero-sum-consecutive-nodes-from-linked-list.py 295
sort-list.py 297
guess-number-higher-or-lower-ii.py 298
flatten-nested-list-iterator.py 299
flatten-binary-tree-to-linked-list.py 300
h-index-ii.py 302
path-sum-ii.py 303
beautiful-arrangement.py 304
rotate-function.py 306
partition-array-for-maximum-sum.py 307
shopping-offers.py 308
construct-binary-tree-from-inorder-and-postorder-traversal.py 310
6
teemo-attacking.py 311
largest-divisible-subset.py 312
word-subsets.py 313
satisfiability-of-equality-equations.py 315
unique-substrings-in-wraparound-string.py 318
exclusive-time-of-functions.py 319
flip-equivalent-binary-trees.py 321
linked-list-cycle-ii.py 323
maximum-subarray-sum-with-one-deletion.py 325
sort-colors.py 326
peeking-iterator.py 327
number-of-matching-subsequences.py 328
find-largest-value-in-each-tree-row.py 329
contiguous-array.py 331
pacific-atlantic-water-flow.py 332
minesweeper.py 334
count-numbers-with-unique-digits.py 337
most-stones-removed-with-same-row-or-column.py 338
previous-permutation-with-one-swap.py 339
spiral-matrix.py 341
invalid-transactions.py 342
counting-bits.py 344
stone-game-ii.py 345
lru-cache.py 346
maximum-product-of-splitted-binary-tree.py 349
valid-tic-tac-toe-state.py 351
decrease-elements-to-make-array-zigzag.py 353
maximum-xor-of-two-numbers-in-an-array.py 354
longest-common-subsequence.py 355
binary-tree-inorder-traversal.py 357
sort-the-matrix-diagonally.py 359
flip-binary-tree-to-match-preorder-traversal.py 360
bulb-switcher-ii.py 361
7
arithmetic-slices.py 363
unique-paths.py 364
bag-of-tokens.py 365
decode-ways.py 366
statistics-from-a-large-sample.py 367
array-nesting.py 369
divide-two-integers.py 370
coin-change.py 372
regions-cut-by-slashes.py 373
letter-combinations-of-a-phone-number.py 375
longest-repeating-character-replacement.py 377
search-in-rotated-sorted-array.py 379
increasing-triplet-subsequence.py 380
permutations-ii.py 382
find-and-replace-pattern.py 383
time-based-key-value-store.py 384
ugly-number-iii.py 386
utf-8-validation.py 388
longest-increasing-subsequence.py 390
last-stone-weight-ii.py 392
largest-number.py 393
coloring-a-border.py 394
validate-stack-sequences.py 395
4sum.py 396
bulb-switcher.py 398
path-in-zigzag-labelled-binary-tree.py 399
break-a-palindrome.py 400
balance-a-binary-search-tree.py 401
verify-preorder-serialization-of-a-binary-tree.py 403
valid-triangle-number.py 405
coin-change-2.py 406
subsets.py 408
kth-smallest-element-in-a-sorted-matrix.py 410
8
word-ladder.py 411
camelcase-matching.py 413
encode-and-decode-tinyurl.py 415
triangle.py 417
get-equal-substrings-within-budget.py 418
score-after-flipping-matrix.py 420
subarray-sums-divisible-by-k.py 421
lowest-common-ancestor-of-deepest-leaves.py 422
3sum-with-multiplicity.py 424
max-consecutive-ones-iii.py 426
adding-two-negabinary-numbers.py 427
map-sum-pairs.py 428
binary-tree-coloring-game.py 430
non-overlapping-intervals.py 432
reverse-substrings-between-each-pair-of-parentheses.py 434
restore-ip-addresses.py 436
random-point-in-non-overlapping-rectangles.py 438
super-ugly-number.py 439
minimum-increment-to-make-array-unique.py 442
find-right-interval.py 443
longest-happy-string.py 445
generate-parentheses.py 447
target-sum.py 448
permutation-in-string.py 449
maximum-swap.py 450
best-time-to-buy-and-sell-stock-with-cooldown.py 451
simplify-path.py 452
maximum-binary-tree.py 454
decode-string.py 456
smallest-string-with-swaps.py 457
optimal-division.py 460
remove-all-adjacent-duplicates-in-string-ii.py 461
clone-graph.py 462
9
wiggle-sort-ii.py 464
unique-binary-search-trees-ii.py 466
remove-nth-node-from-end-of-list.py 468
valid-square.py 469
water-and-jug-problem.py 470
delete-columns-to-make-sorted-ii.py 471
evaluate-reverse-polish-notation.py 472
validate-ip-address.py 473
single-number-iii.py 475
four-divisors.py 477
next-permutation.py 479
longest-string-chain.py 481
reduce-array-size-to-the-half.py 482
ugly-number-ii.py 484
design-circular-deque.py 486
smallest-integer-divisible-by-k.py 489
dota2-senate.py 491
wiggle-subsequence.py 493
gas-station.py 495
deepest-leaves-sum.py 497
check-if-word-is-valid-after-substitutions.py 498
subsets-ii.py 500
insufficient-nodes-in-root-to-leaf-paths.py 502
maximum-binary-tree-ii.py 503
longest-substring-with-at-least-k-repeating-characters.py 505
diagonal-traverse.py 506
evaluate-division.py 508
minimum-time-difference.py 510
binary-tree-zigzag-level-order-traversal.py 511
minimum-score-triangulation-of-polygon.py 512
multiply-strings.py 514
circular-array-loop.py 516
largest-1-bordered-square.py 518
10
check-if-a-string-contains-all-binary-codes-of-size-k.py 519
valid-sudoku.py 521
can-i-win.py 523
additive-number.py 525
3sum.py 527
minimum-cost-tree-from-leaf-values.py 529
longest-palindromic-subsequence.py 530
closest-divisors.py 531
minimum-moves-to-equal-array-elements-ii.py 533
smallest-subsequence-of-distinct-characters.py 535
find-bottom-left-tree-value.py 537
combinations.py 539
capacity-to-ship-packages-within-d-days.py 541
game-of-life.py 543
online-stock-span.py 545
interval-list-intersections.py 546
lexicographical-numbers.py 547
most-frequent-subtree-sum.py 548
k-closest-points-to-origin.py 549
implement-magic-dictionary.py 551
h-index.py 553
construct-binary-tree-from-preorder-and-postorder-traversal.py 555
integer-break.py 557
predict-the-winner.py 559
remove-covered-intervals.py 561
find-peak-element.py 562
reorder-list.py 563
maximum-length-of-pair-chain.py 564
integer-to-roman.py 565
rotting-oranges.py 567
snapshot-array.py 569
longest-word-in-dictionary-through-deleting.py 571
reconstruct-itinerary.py 572
11
add-two-numbers.py 574
prison-cells-after-n-days.py 575
path-with-maximum-gold.py 576
unique-binary-search-trees.py 578
minimum-domino-rotations-for-equal-row.py 579
reveal-cards-in-increasing-order.py 581
fruit-into-baskets.py 583
binary-tree-preorder-traversal.py 585
reverse-words-in-a-string.py 587
swap-nodes-in-pairs.py 588
convert-sorted-list-to-binary-search-tree.py 589
shortest-path-in-binary-matrix.py 591
number-of-enclaves.py 592
word-search.py 594
iterator-for-combination.py 596
complete-binary-tree-inserter.py 599
print-foobar-alternately.py 601
minimum-remove-to-make-valid-parentheses.py 603
stone-game.py 605
longest-substring-without-repeating-characters.py 606
combination-sum-ii.py 607
task-scheduler.py 608
find-minimum-in-rotated-sorted-array.py 610
maximum-width-of-binary-tree.py 611
fraction-addition-and-subtraction.py 613
top-k-frequent-elements.py
# Example 2:
#
# Input: nums = [1], k = 1
# Output: [1]# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
12
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
counts = collections.Counter(nums)
buckets = [[] for _ in xrange(len(nums)+1)]
for i, count in counts.iteritems():
buckets[count].append(i)
result = []
for i in reversed(xrange(len(buckets))):
for j in xrange(len(buckets[i])):
result.append(buckets[i][j])
if len(result) == k:
return result
return result
result = []
for i in xrange(k):
result.append(p[i][1])
return result
13
return
elif new_pivot_idx > k:
right = new_pivot_idx - 1
else: # new_pivot_idx < k.
left = new_pivot_idx + 1
# Time: O(nlogk)
# Space: O(n)
class Solution3(object):
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
return [key for key, _ in collections.Counter(nums).most_common(k)]
14
reconstruct-original-digits-from-english.py
# Given a non-empty string containing an out-of-order English representation of
# digits 0-9, output the digits in ascending order.
#
# Note:
#
#
# Input contains only lowercase English letters.
# Input is guaranteed to be valid and can be transformed to its original digits.
# That means invalid inputs such as "abc" or "zerone" are not permitted.
# Input length is less than 50,000.
#
#
#
# Example 1:
#
# Input: "owoztneoer"
#
# Output: "012"
#
#
#
# Example 2:
#
# Input: "fviefuro"
#
# Output: "45"# Time: O(n)
# Space: O(1)
class Solution(object):
def originalDigits(self, s):
"""
:type s: str
:rtype: str
"""
# The count of each char in each number string.
cnts = [Counter(_) for _ in ["zero", "one", "two", "three", \
"four", "five", "six", "seven", \
"eight", "nine"]]
cnt = Counter(list(s))
res = []
for i in order:
while cnt[unique_chars[i]] > 0:
cnt -= cnts[i]
res.append(i)
res.sort()
15
compare-version-numbers.py
# Compare two version numbers version1 and version2.
#
# If version1 > version2 return 1; if version1 < version2 return -1;otherwise
# return 0.
#
# You may assume that the version strings are non-empty and contain only digits
# and the . character.
# The . character does not represent a decimal point and is used to separate
# number sequences.
# For instance, 2.5 is not "two and a half" or "half way to version three", it
# is the fifth second-level revision of the second first-level revision.
# You may assume the default revision number for each level of a version number
# to be 0. For example, version number 3.4 has a revision number of 3 and 4 for
# its first and second level revision number. Its third and fourth level revision
# number are both 0.
#
#
#
# Example 1:
# Input: version1 = "0.1", version2 = "1.1"
# Output: -1
#
# Example 2:
# Input: version1 = "1.0.1", version2 = "1"
# Output: 1
#
# Example 3:
# Input: version1 = "7.5.2.4", version2 = "7.5.3"
# Output: -1
#
# Example 4:
# Input: version1 = "1.01", version2 = "1.001"
# Output: 0
# Explanation: Ignoring leading zeroes, both “01” and “001" represent the same
# number “1”
#
# Example 5:
# Input: version1 = "1.0", version2 = "1.0.0"
# Output: 0
# Explanation: The first version number does not have a third level revision
# number, which means its third level revision number is default to "0"
#
#
#
# Note:
#
# Version strings are composed of numeric strings separated by dots . and this
# numeric strings may have leading zeroes.
# Version strings do not start or end with dots, and they will not be two
# consecutive dots.# Time: O(n)
# Space: O(1)
import itertools
class Solution(object):
def compareVersion(self, version1, version2):
"""
16
:type version1: str
:type version2: str
:rtype: int
"""
n1, n2 = len(version1), len(version2)
i, j = 0, 0
while i < n1 or j < n2:
v1, v2 = 0, 0
while i < n1 and version1[i] != '.':
v1 = v1 * 10 + int(version1[i])
i += 1
while j < n2 and version2[j] != '.':
v2 = v2 * 10 + int(version2[j])
j += 1
if v1 != v2:
return 1 if v1 > v2 else -1
i += 1
j += 1
return 0
# Time: O(n)
# Space: O(n)
class Solution2(object):
def compareVersion(self, version1, version2):
"""
:type version1: str
:type version2: str
:rtype: int
"""
v1, v2 = version1.split("."), version2.split(".")
i = 0
while i < len(v1):
if int(v1[i]) > int(v2[i]):
return 1
elif int(v1[i]) < int(v2[i]):
return -1
else:
i += 1
return 0
17
v2.append(0)
else:
v1.append(0)
return cmp(v1, v2)
18
combination-sum-iv.py
# Given an integer array with all positive numbers and no duplicates, find the
# number of possible combinations that add up to a positive integer target.
#
# Example:
#
# nums = [1, 2, 3]
# target = 4
#
# The possible combination ways are:
# (1, 1, 1, 1)
# (1, 1, 2)
# (1, 2, 1)
# (1, 3)
# (2, 1, 1)
# (2, 2)
# (3, 1)
#
# Note that different sequences are counted as different combinations.
#
# Therefore the output is 7.
#
#
#
#
# Follow up:
#
# What if negative numbers are allowed in the given array?
#
# How does it change the problem?
#
# What limitation we need to add to the question to allow negative numbers?
#
# Credits:
#
# Special thanks to @pbrother for adding this problem and creating all test
# cases.# Time: O(nlon + n * t), t is the value of target.
# Space: O(t)
class Solution(object):
def combinationSum4(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
dp = [0] * (target+1)
dp[0] = 1
nums.sort()
return dp[target]
19
koko-eating-bananas.py
# Koko loves to eat bananas. There are N piles of bananas, the i-th pile has
# piles[i] bananas. The guards have gone and will come back in H hours.
#
# Koko can decide her bananas-per-hour eating speed of K. Each hour, she
# chooses some pile of bananas, and eats K bananas from that pile. If the pile
# has less than K bananas, she eats all of them instead, and won't eat any more
# bananas during this hour.
#
# Koko likes to eat slowly, but still wants to finish eating all the bananas
# before the guards come back.
#
# Return the minimum integer K such that she can eat all the bananas within H
# hours.
#
#
# Example 1:
# Input: piles = [3,6,7,11], H = 8
# Output: 4
# Example 2:
# Input: piles = [30,11,23,4,20], H = 5
# Output: 30
# Example 3:
# Input: piles = [30,11,23,4,20], H = 6
# Output: 23
#
#
# Constraints:
#
#
# 1 <= piles.length <= 10^4
# piles.length <= H <= 10^9
# 1 <= piles[i] <= 10^9# Time: O(nlogr)
# Space: O(1)
class Solution(object):
def minEatingSpeed(self, piles, H):
"""
:type piles: List[int]
:type H: int
:rtype: int
"""
def possible(piles, H, K):
return sum((pile-1)//K+1 for pile in piles) <= H
20
random-pick-with-weight.py
# Given an array of positive integers w. where w[i] describes the weight of
# ith index (0-indexed).
#
# We need to call the function pickIndex() which randomly returns an integer in
# the range [0, w.length - 1]. pickIndex() should return the integer proportional
# to its weight in the w array. For example, for w = [1, 3], the probability of
# picking index 0 is 1 / (1 + 3) = 0.25 (i.e 25%) while the probability of picking
# index 1 is 3 / (1 + 3) = 0.75 (i.e 75%).
#
# More formally, the probability of picking index i is w[i] / sum(w).
#
#
# Example 1:
#
# Input
# ["Solution","pickIndex"]
# [[[1]],[]]
# Output
# [null,0]
#
# Explanation
# Solution solution = new Solution([1]);
# solution.pickIndex(); // return 0. Since there is only one single element on
# the array the only option is to return the first element.
#
#
# Example 2:
#
# Input
# ["Solution","pickIndex","pickIndex","pickIndex","pickIndex","pickIndex"]
# [[[1,3]],[],[],[],[],[]]
# Output
# [null,1,1,1,1,0]
#
# Explanation
# Solution solution = new Solution([1, 3]);
# solution.pickIndex(); // return 1. It's returning the second element (index =
# 1) that has probability of 3/4.
# solution.pickIndex(); // return 1
# solution.pickIndex(); // return 1
# solution.pickIndex(); // return 1
# solution.pickIndex(); // return 0. It's returning the first element (index =
# 0) that has probability of 1/4.
#
# Since this is a randomization problem, multiple answers are allowed so the
# following outputs can be considered correct :
# [null,1,1,1,1,0]
# [null,1,1,1,1,1]
# [null,1,1,1,0,0]
# [null,1,1,1,0,1]
# [null,1,0,1,0,0]
# ......
# and so on.
#
#
#
# Constraints:
#
21
#
# 1 <= w.length <= 10000
# 1 <= w[i] <= 10^5
# pickIndex will be called at most 10000 times.# Time: ctor: O(n)
# pickIndex: O(logn)
# Space: O(n)
import random
import bisect
class Solution(object):
def pickIndex(self):
"""
:rtype: int
"""
target = random.randint(0, self.__prefix_sum[-1]-1)
return bisect.bisect_right(self.__prefix_sum, target)
22
find-k-closest-elements.py
# Given a sorted array arr, two integers k and x, find the k closest elements to
# x in the array. The result should also be sorted in ascending order. If there is
# a tie, the smaller elements are always preferred.
#
#
# Example 1:
# Input: arr = [1,2,3,4,5], k = 4, x = 3
# Output: [1,2,3,4]
# Example 2:
# Input: arr = [1,2,3,4,5], k = 4, x = -1
# Output: [1,2,3,4]
#
#
# Constraints:
#
#
# 1 <= k <= arr.length
# 1 <= arr.length <= 10^4
# Absolute value of elements in the array and x will not exceed 104# Time: O(logn + k)
# Space: O(1)
import bisect
class Solution(object):
def findClosestElements(self, arr, k, x):
"""
:type arr: List[int]
:type k: int
:type x: int
:rtype: List[int]
"""
i = bisect.bisect_left(arr, x)
left, right = i-1, i
while k:
if right >= len(arr) or \
(left >= 0 and abs(arr[left]-x) <= abs(arr[right]-x)):
left -= 1
else:
right += 1
k -= 1
return arr[left+1:right]
23
jump-game-iii.py
# Given an array of non-negative integers arr, you are initially positioned at
# start index of the array. When you are at index i, you can jump to i + arr[i] or
# i - arr[i], check if you can reach to any index with value 0.
#
# Notice that you can not jump outside of the array at any time.
#
#
# Example 1:
#
# Input: arr = [4,2,3,0,3,1,2], start = 5
# Output: true
# Explanation:
# All possible ways to reach at index 3 with value 0 are:
# index 5 -> index 4 -> index 1 -> index 3
# index 5 -> index 6 -> index 4 -> index 1 -> index 3
#
#
# Example 2:
#
# Input: arr = [4,2,3,0,3,1,2], start = 0
# Output: true
# Explanation:
# One possible way to reach at index 3 with value 0 is:
# index 0 -> index 4 -> index 1 -> index 3
#
#
# Example 3:
#
# Input: arr = [3,0,2,1,2], start = 2
# Output: false
# Explanation: There is no way to reach at index 1 with value 0.
#
#
#
# Constraints:
#
#
# 1 <= arr.length <= 5 * 10^4
# 0 <= arr[i] < arr.length
# 0 <= start < arr.length# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def canReach(self, arr, start):
"""
:type arr: List[int]
:type start: int
:rtype: bool
"""
q, lookup = collections.deque([start]), set([start])
while q:
i = q.popleft()
if not arr[i]:
return True
for j in [i-arr[i], i+arr[i]]:
24
if 0 <= j < len(arr) and j not in lookup:
lookup.add(j)
q.append(j)
return False
25
single-number-ii.py
# Given a non-empty array of integers, every element appears three times except
# for one, which appears exactly once. Find that single one.
#
# Note:
#
# Your algorithm should have a linear runtime complexity. Could you implement it
# without using extra memory?
#
# Example 1:
#
# Input: [2,2,3,2]
# Output: 3
#
#
# Example 2:
#
# Input: [0,1,0,1,0,1,99]
# Output: 99# Time: O(n)
# Space: O(1)
import collections
class Solution(object):
# @param A, a list of integer
# @return an integer
def singleNumber(self, A):
one, two = 0, 0
for x in A:
one, two = (~x & one) | (x & ~one & ~two), (~x & two) | (x & one)
return one
class Solution2(object):
# @param A, a list of integer
# @return an integer
def singleNumber(self, A):
one, two, carry = 0, 0, 0
for x in A:
two |= one & x
one ^= x
carry = one & two
one &= ~carry
two &= ~carry
return one
class Solution3(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
return (collections.Counter(list(set(nums)) * 3) - collections.Counter(nums)).keys()[0]
class Solution4(object):
def singleNumber(self, nums):
26
"""
:type nums: List[int]
:rtype: int
"""
return (sum(set(nums)) * 3 - sum(nums)) / 2
27
array-of-doubled-pairs.py
# Example 1:
#
# Input: [3,1,3,6]
# Output: false
#
#
#
# Example 2:
#
# Input: [2,1,2,6]
# Output: false
#
#
#
# Example 3:
#
# Input: [4,-2,2,-4]
# Output: true
# Explanation: We can take two groups, [-2,-4] and [2,4] to form [-2,-4,2,4] or
# [2,4,-2,-4].
#
#
#
# Example 4:
#
# Input: [1,2,4,16,8,4]
# Output: false
#
#
#
#
# Note:
#
#
# 0 <= A.length <= 30000
# A.length is even
# -100000 <= A[i] <= 100000# Time: O(n + klogk)
# Space: O(k)
import collections
class Solution(object):
def canReorderDoubled(self, A):
"""
:type A: List[int]
:rtype: bool
"""
count = collections.Counter(A)
for x in sorted(count, key=abs):
if count[x] > count[2*x]:
return False
count[2*x] -= count[x]
return True
28
jump-game.py
# Given an array of non-negative integers, you are initially positioned at the
# first index of the array.
#
# Each element in the array represents your maximum jump length at that
# position.
#
# Determine if you are able to reach the last index.
#
#
# Example 1:
#
# Input: nums = [2,3,1,1,4]
# Output: true
# Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
#
#
# Example 2:
#
# Input: nums = [3,2,1,0,4]
# Output: false
# Explanation: You will always arrive at index 3 no matter what. Its maximum
# jump length is 0, which makes it impossible to reach the last index.
#
#
#
# Constraints:
#
#
# 1 <= nums.length <= 3 * 10^4
# 0 <= nums[i][j] <= 10^5# Time: O(n)
# Space: O(1)
class Solution(object):
# @param A, a list of integers
# @return a boolean
def canJump(self, A):
reachable = 0
for i, length in enumerate(A):
if i > reachable:
break
reachable = max(reachable, i + length)
return reachable >= len(A) - 1
29
remove-k-digits.py
# Given a non-negative integer num represented as a string, remove k digits from
# the number so that the new number is the smallest possible.
#
#
# Note:
#
#
# The length of num is less than 10002 and will be k.
# The given num does not contain any leading zero.
#
#
#
#
# Example 1:
# Input: num = "1432219", k = 3
# Output: "1219"
# Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219
# which is the smallest.
#
#
#
# Example 2:
# Input: num = "10200", k = 1
# Output: "200"
# Explanation: Remove the leading 1 and the number is 200. Note that the output
# must not contain leading zeroes.
#
#
#
# Example 3:
# Input: num = "10", k = 2
# Output: "0"
# Explanation: Remove all the digits from the number and it is left with nothing
# which is 0.# Time: O(n)
# Space: O(n)
class Solution(object):
def removeKdigits(self, num, k):
"""
:type num: str
:type k: int
:rtype: str
"""
result = []
for d in num:
while k and result and result[-1] > d:
result.pop()
k -= 1
result.append(d)
return ''.join(result).lstrip('0')[:-k or None] or '0'
30
construct-quad-tree.py
# Given a n * n matrix grid of 0's and 1's only. We want to represent the grid
# with a Quad-Tree.
#
# Return the root of the Quad-Tree representing the grid.
#
# Notice that you can assign the value of a node to True or False when isLeaf is
# False, and both are accepted in the answer.
#
# A Quad-Tree is a tree data structure in which each internal node has exactly
# four children. Besides, each node has two attributes:
#
#
# val: True if the node represents a grid of 1's or False if the node
# represents a grid of 0's.
# isLeaf: True if the node is leaf node on the tree or False if the node
# has the four children.
#
#
# class Node {
# public boolean val;
# public boolean isLeaf;
# public Node topLeft;
# public Node topRight;
# public Node bottomLeft;
# public Node bottomRight;
# }
#
# We can construct a Quad-Tree from a two-dimensional area using the following
# steps:
#
#
# If the current grid has the same value (i.e all 1's or all 0's) set
# isLeaf True and set val to the value of the grid and set the four children to
# Null and stop.
# If the current grid has different values, set isLeaf to False and set
# val to any value and divide the current grid into four sub-grids as shown in the
# photo.
# Recurse for each of the children with the proper sub-grid.
#
#
# If you want to know more about the Quad-Tree, you can refer to the wiki.
#
# Quad-Tree format:
#
# The output represents the serialized format of a Quad-Tree using level order
# traversal, where null signifies a path terminator where no node exists below.
#
# It is very similar to the serialization of the binary tree. The only
# difference is that the node is represented as a list [isLeaf, val].
#
# If the value of isLeaf or val is True we represent it as 1 in the
# list [isLeaf, val] and if the value of isLeaf or val is False we represent it as
# 0.
#
#
# Example 1:
#
# Input: grid = [[0,1],[1,0]]
31
# Output: [[0,1],[1,0],[1,1],[1,1],[1,0]]
# Explanation: The explanation of this example is shown below:
# Notice that 0 represnts False and 1 represents True in the photo representing
# the Quad-Tree.
#
#
#
# Example 2:
#
#
#
# Input: grid = [[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,1,1,1,1],[1,1,1,1,
# 1,1,1,1],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0],[1,1,1,1,0,0,0,0]
# ]
# Output:
# [[0,1],[1,1],[0,1],[1,1],[1,0],null,null,null,null,[1,0],[1,0],[1,1],[1,1]]
# Explanation: All values in the grid are not the same. We divide the grid into
# four sub-grids.
# The topLeft, bottomLeft and bottomRight each has the same value.
# The topRight have different values so we divide it into 4 sub-grids where each
# has the same value.
# Explanation is shown in the photo below:
#
#
#
# Example 3:
#
# Input: grid = [[1,1],[1,1]]
# Output: [[1,1]]
#
#
# Example 4:
#
# Input: grid = [[0]]
# Output: [[1,0]]
#
#
# Example 5:
#
# Input: grid = [[1,1,0,0],[1,1,0,0],[0,0,1,1],[0,0,1,1]]
# Output: [[0,1],[1,1],[1,0],[1,0],[1,1]]
#
#
#
# Constraints:
#
#
# n == grid.length == grid[i].length
# n == 2^x where 0 <= x <= 6# Time: O(n)
# Space: O(h)
class Node(object):
def __init__(self, val, isLeaf, topLeft, topRight, bottomLeft, bottomRight):
self.val = val
self.isLeaf = isLeaf
self.topLeft = topLeft
self.topRight = topRight
self.bottomLeft = bottomLeft
self.bottomRight = bottomRight
32
class Solution(object):
def construct(self, grid):
"""
:type grid: List[List[int]]
:rtype: Node
"""
def dfs(grid, x, y, l):
if l == 1:
return Node(grid[x][y] == 1, True, None, None, None, None)
half = l // 2
topLeftNode = dfs(grid, x, y, half)
topRightNode = dfs(grid, x, y+half, half)
bottomLeftNode = dfs(grid, x+half, y, half)
bottomRightNode = dfs(grid, x+half, y+half, half)
if topLeftNode.isLeaf and topRightNode.isLeaf and \
bottomLeftNode.isLeaf and bottomRightNode.isLeaf and \
topLeftNode.val == topRightNode.val == bottomLeftNode.val == bottomRightNode.val:
return Node(topLeftNode.val, True, None, None, None, None)
return Node(True, False, topLeftNode, topRightNode, bottomLeftNode, bottomRightNode)
if not grid:
return None
return dfs(grid, 0, 0, len(grid))
33
search-in-rotated-sorted-array-ii.py
# Suppose an array sorted in ascending order is rotated at some pivot unknown to
# you beforehand.
#
# (i.e., [0,0,1,2,2,5,6] might become [2,5,6,0,0,1,2]).
#
# You are given a target value to search. If found in the array return true,
# otherwise return false.
#
# Example 1:
#
# Input: nums = [2,5,6,0,0,1,2], target = 0
# Output: true
#
#
# Example 2:
#
# Input: nums = [2,5,6,0,0,1,2], target = 3
# Output: false
#
# Follow up:
#
#
# This is a follow up problem to Search in Rotated Sorted Array, where
# nums may contain duplicates.
# Would this affect the run-time complexity? How and why?# Time: O(logn)
# Space: O(1)
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left, right = 0, len(nums) - 1
if nums[mid] == target:
return True
elif nums[mid] == nums[left]:
left += 1
elif (nums[mid] > nums[left] and nums[left] <= target < nums[mid]) or \
(nums[mid] < nums[left] and not (nums[mid] < target <= nums[right])):
right = mid - 1
else:
left = mid + 1
return False
34
delete-operation-for-two-strings.py
# Given two words word1 and word2, find the minimum number of steps required to
# make word1 and word2 the same, where in each step you can delete one character
# in either string.
#
#
# Example 1:
#
# Input: "sea", "eat"
# Output: 2
# Explanation: You need one step to make "sea" to "ea" and another step to make
# "eat" to "ea".
#
#
#
# Note:
#
#
# The length of given words won't exceed 500.
# Characters in given words can only be lower-case letters.# Time: O(m * n)
# Space: O(n)
class Solution(object):
def minDistance(self, word1, word2):
"""
:type word1: str
:type word2: str
:rtype: int
"""
m, n = len(word1), len(word2)
dp = [[0] * (n+1) for _ in range(2)]
for i in range(m):
for j in range(n):
dp[(i+1)%2][j+1] = max(dp[i%2][j+1], \
dp[(i+1)%2][j], \
dp[i%2][j] + (word1[i] == word2[j]))
print(dp)
return m + n - 2*dp[m%2][n]
if __name__ == '__main__':
s, t = "mart", "karma"
ret = Solution().minDistance(s, t)
ret = Solution().minDistance2(s, t)
35
print(ret)
36
length-of-longest-fibonacci-subsequence.py
# A sequence X_1, X_2, ..., X_n is fibonacci-like if:
#
#
# n >= 3
# X_i + X_{i+1} = X_{i+2} for all i + 2 <= n
#
#
# Given a strictly increasing array A of positive integers forming a sequence,
# find the length of the longest fibonacci-like subsequence of A. If one does not
# exist, return 0.
#
# (Recall that a subsequence is derived from another sequence A by deleting any
# number of elements (including none) from A, without changing the order of the
# remaining elements. For example, [3, 5, 8] is a subsequence of [3, 4, 5, 6, 7,
# 8].)
#
#
#
#
#
#
# Example 1:
#
# Input: [1,2,3,4,5,6,7,8]
# Output: 5
# Explanation:
# The longest subsequence that is fibonacci-like: [1,2,3,5,8].
#
#
# Example 2:
#
# Input: [1,3,7,11,12,14,18]
# Output: 3
# Explanation:
# The longest subsequence that is fibonacci-like:
# [1,11,12], [3,11,14] or [7,11,18].
#
#
#
#
# Note:
#
#
# 3 <= A.length <= 1000
# 1 <= A[0] < A[1] < ... < A[A.length - 1] <= 10^9
# (The time limit has been reduced by 50% for submissions in Java, C, and
# C++.)# Time: O(n^2)
# Space: O(n)
class Solution(object):
def lenLongestFibSubseq(self, A):
"""
:type A: List[int]
:rtype: int
"""
lookup = set(A)
result = 2
for i in xrange(len(A)):
37
for j in xrange(i+1, len(A)):
x, y, l = A[i], A[j], 2
while x+y in lookup:
x, y, l = y, x+y, l+1
result = max(result, l)
return result if result > 2 else 0
38
bitwise-ors-of-subarrays.py
# Example 1:
#
# Input: [0]
# Output: 1
# Explanation:
# There is only one possible result: 0.
#
#
#
# Example 2:
#
# Input: [1,1,2]
# Output: 3
# Explanation:
# The possible subarrays are [1], [1], [2], [1, 1], [1, 2], [1, 1, 2].
# These yield the results 1, 1, 2, 1, 3, 3.
# There are 3 unique values, so the answer is 3.
#
#
#
# Example 3:
#
# Input: [1,2,4]
# Output: 6
# Explanation:
# The possible results are 1, 2, 3, 4, 6, and 7.# Time: O(32 * n)
# Space: O(1)
class Solution(object):
def subarrayBitwiseORs(self, A):
"""
:type A: List[int]
:rtype: int
"""
result, curr = set(), {0}
for i in A:
curr = {i} | {i | j for j in curr}
result |= curr
return len(result)
39
check-completeness-of-a-binary-tree.py
# Example 2:
#
#
#
# Input: [1,2,3,4,5,null,7]
# Output: false
# Explanation: The node with value 7 isn't as far left as possible.# Time: O(n)
# Space: O(w)
class Solution(object):
def isCompleteTree(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
end = False
current = [root]
while current:
next_level = []
for node in current:
if not node:
end = True
continue
if end:
return False
next_level.append(node.left)
next_level.append(node.right)
current = next_level
return True
# Time: O(n)
# Space: O(w)
class Solution2(object):
def isCompleteTree(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
prev_level, current = [], [(root, 1)]
count = 0
while current:
count += len(current)
next_level = []
for node, v in current:
if not node:
continue
next_level.append((node.left, 2*v))
next_level.append((node.right, 2*v+1))
prev_level, current = current, next_level
40
return prev_level[-1][1] == count
41
increasing-subsequences.py
# Given an integer array, your task is to find all the different possible
# increasing subsequences of the given array, and the length of an increasing
# subsequence should be at least 2.
#
#
#
# Example:
#
# Input: [4, 6, 7, 7]
# Output: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7],
# [4,7,7]]
#
#
#
# Constraints:
#
#
# The length of the given array will not exceed 15.
# The range of integer in the given array is [-100,100].
# The given array may contain duplicates, and two equal integers should
# also be considered as a special case of increasing sequence.# Time: O(n * 2^n)
# Space: O(n), longest possible path in tree, which is if all numbers are increasing.
class Solution(object):
def findSubsequences(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
def findSubsequencesHelper(nums, pos, seq, result):
if len(seq) >= 2:
result.append(list(seq))
lookup = set()
for i in xrange(pos, len(nums)):
if (not seq or nums[i] >= seq[-1]) and \
nums[i] not in lookup:
lookup.add(nums[i])
seq.append(nums[i])
findSubsequencesHelper(nums, i+1, seq, result)
seq.pop()
42
binary-string-with-substrings-representing-1-to-n.py
# Given a binary string S (a string consisting only of '0' and '1's) and a
# positive integer N, return true if and only if for every integer X from 1 to N,
# the binary representation of X is a substring of S.
#
#
#
# Example 1:
#
# Input: S = "0110", N = 3
# Output: true
#
#
# Example 2:
#
# Input: S = "0110", N = 4
# Output: false
#
#
#
#
# Note:
#
#
# 1 <= S.length <= 1000
# 1 <= N <= 10^9# Time: O(n^2), n is the length of S
# Space: O(1)
class Solution(object):
def queryString(self, S, N):
"""
:type S: str
:type N: int
:rtype: bool
"""
# since S with length n has at most different n-k+1 k-digit numbers
# => given S with length n, valid N is at most 2(n-k+1)
# => valid N <= 2(n-k+1) < 2n = 2 * S.length
return all(bin(i)[2:] in S for i in reversed(xrange(N//2, N+1)))
43
valid-parenthesis-string.py
# Given a string containing only three types of characters: '(', ')' and '*',
# write a function to check whether this string is valid. We define the validity
# of a string by these rules:
#
# Any left parenthesis '(' must have a corresponding right parenthesis ')'.
# Any right parenthesis ')' must have a corresponding left parenthesis '('.
# Left parenthesis '(' must go before the corresponding right parenthesis ')'.
# '*' could be treated as a single right parenthesis ')' or a single left
# parenthesis '(' or an empty string.
# An empty string is also valid.
#
#
#
# Example 1:
#
# Input: "()"
# Output: True
#
#
#
# Example 2:
#
# Input: "(*)"
# Output: True
#
#
#
# Example 3:
#
# Input: "(*))"
# Output: True
#
#
#
# Note:
#
#
# The string size will be in the range [1, 100].# Time: O(n)
# Space: O(1)
class Solution(object):
def checkValidString(self, s):
"""
:type s: str
:rtype: bool
"""
lower, upper = 0, 0 # keep lower bound and upper bound of '(' counts
for c in s:
lower += 1 if c == '(' else -1
upper -= 1 if c == ')' else -1
if upper < 0: break
lower = max(lower, 0)
return lower == 0 # range of '(' count is valid
44
total-hamming-distance.py
# The Hamming distance between two integers is the number of positions at which
# the corresponding bits are different.
#
# Now your job is to find the total Hamming distance between all pairs of the
# given numbers.
#
#
# Example:
#
# Input: 4, 14, 2
#
# Output: 6
#
# Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is
# 0010 (just
# showing the four bits relevant in this case). So the answer will be:
# HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 +
# 2 + 2 = 6.
#
#
#
# Note:
#
#
# Elements of the given array are in the range of 0 to 10^9
# Length of the array will not exceed 10^4.# Time: O(n)
# Space: O(1)
class Solution(object):
def totalHammingDistance(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
result = 0
for i in xrange(32):
counts = [0] * 2
for num in nums:
counts[(num >> i) & 1] += 1
result += counts[0] * counts[1]
return result
45
serialize-and-deserialize-bst.py
# Serialization is the process of converting a data structure or object into a
# sequence of bits so that it can be stored in a file or memory buffer, or
# transmitted across a network connection link to be reconstructed later in the
# same or another computer environment.
#
# Design an algorithm to serialize and deserialize a binary search tree. There
# is no restriction on how your serialization/deserialization algorithm should
# work. You just need to ensure that a binary search tree can be serialized to a
# string and this string can be deserialized to the original tree structure.
#
# The encoded string should be as compact as possible.
#
# Note: Do not use class member/global/static variables to store states. Your
# serialize and deserialize algorithms should be stateless.# Time: O(n)
# Space: O(h)
import collections
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Codec(object):
vals = []
serializeHelper(root, vals)
46
node = TreeNode(val)
node.left = deserializeHelper(minVal, val, vals)
node.right = deserializeHelper(val, maxVal, vals)
return node
else:
return None
47
product-of-array-except-self.py
# Given an array nums of n integers where n > 1, return an array output such
# that output[i] is equal to the product of all the elements of nums except
# nums[i].
#
# Example:
#
# Input: [1,2,3,4]
# Output: [24,12,8,6]
#
#
# Constraint: It's guaranteed that the product of the elements of any prefix or
# suffix of the array (including the whole array) fits in a 32 bit integer.
#
# Note: Please solve it without division and in O(n).
#
# Follow up:
#
# Could you solve it with constant space complexity? (The output array does not
# count as extra space for the purpose of space complexity analysis.)# Time: O(n)
# Space: O(1)
class Solution(object):
# @param {integer[]} nums
# @return {integer[]}
def productExceptSelf(self, nums):
if not nums:
return []
right_product = 1
for i in xrange(len(nums) - 2, -1, -1):
right_product *= nums[i + 1]
left_product[i] = left_product[i] * right_product
return left_product
48
queue-reconstruction-by-height.py
# Suppose you have a random list of people standing in a queue. Each person is
# described by a pair of integers (h, k), where h is the height of the person and
# k is the number of people in front of this person who have a height greater than
# or equal to h. Write an algorithm to reconstruct the queue.
#
# Note:
#
# The number of people is less than 1,100.
#
#
# Example
#
# Input:
# [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
#
# Output:
# [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]# Time: O(n * sqrt(n))
# Space: O(n)
class Solution(object):
def reconstructQueue(self, people):
"""
:type people: List[List[int]]
:rtype: List[List[int]]
"""
people.sort(key=lambda h_k: (-h_k[0], h_k[1]))
blocks = [[]]
for p in people:
index = p[1]
# Time: O(n^2)
# Space: O(n)
class Solution2(object):
def reconstructQueue(self, people):
"""
:type people: List[List[int]]
:rtype: List[List[int]]
"""
people.sort(key=lambda h_k1: (-h_k1[0], h_k1[1]))
result = []
for p in people:
result.insert(p[1], p)
return result
49
building-h2o.py
# There are two kinds of threads, oxygen and hydrogen. Your goal is to group
# these threads to form water molecules. There is a barrier where each thread has
# to wait until a complete molecule can be formed. Hydrogen and oxygen threads
# will be given releaseHydrogen and releaseOxygen methods respectively, which will
# allow them to pass the barrier. These threads should pass the barrier in groups
# of three, and they must be able to immediately bond with each other to form a
# water molecule. You must guarantee that all the threads from one molecule bond
# before any other threads from the next molecule do.
#
# In other words:
#
#
# If an oxygen thread arrives at the barrier when no hydrogen threads are
# present, it has to wait for two hydrogen threads.
# If a hydrogen thread arrives at the barrier when no other threads are
# present, it has to wait for an oxygen thread and another hydrogen thread.
#
#
# We don’t have to worry about matching the threads up explicitly; that is, the
# threads do not necessarily know which other threads they are paired up with. The
# key is just that threads pass the barrier in complete sets; thus, if we examine
# the sequence of threads that bond and divide them into groups of three, each
# group should contain one oxygen and two hydrogen threads.
#
# Write synchronization code for oxygen and hydrogen molecules that enforces
# these constraints.
#
#
#
#
#
#
# Example 1:
#
# Input: "HOH"
# Output: "HHO"
# Explanation: "HOH" and "OHH" are also valid answers.
#
#
#
# Example 2:
#
# Input: "OOHHHH"
# Output: "HHOHHO"
# Explanation: "HOHHHO", "OHHHHO", "HHOHOH", "HOHHOH", "OHHHOH", "HHOOHH",
# "HOHOHH" and "OHHOHH" are also valid answers.
#
#
#
#
#
# Constraints:
#
#
# Total length of input string will be 3n, where 1 n 20.
# Total number of H will be 2n in the input string.
# Total number of O will be n in the input string.# Time: O(n)
# Space: O(1)
50
import threading
class H2O(object):
def __init__(self):
self.__l = threading.Lock()
self.__nH = 0
self.__nO = 0
self.__releaseHydrogen = None
self.__releaseOxygen = None
def __output(self):
while self.__nH >= 2 and \
self.__nO >= 1:
self.__nH -= 2
self.__nO -= 1
self.__releaseHydrogen()
self.__releaseHydrogen()
self.__releaseOxygen()
# Time: O(n)
# Space: O(1)
# TLE
class H2O2(object):
def __init__(self):
self.__nH = 0
self.__nO = 0
self.__cv = threading.Condition()
51
"""
with self.__cv:
while 2*(self.__nO+1) - self.__nH > 2:
self.__cv.wait()
self.__nO += 1
# releaseOxygen() outputs "O". Do not change or remove this line.
releaseOxygen()
self.__cv.notifyAll()
52
next-greater-element-ii.py
# Given a circular array (the next element of the last element is the first
# element of the array), print the Next Greater Number for every element. The Next
# Greater Number of a number x is the first greater number to its traversing-order
# next in the array, which means you could search circularly to find its next
# greater number. If it doesn't exist, output -1 for this number.
#
#
# Example 1:
#
# Input: [1,2,1]
# Output: [2,-1,2]
# Explanation: The first 1's next greater number is 2;
# The number 2 can't find next greater number;
# The second 1's next greater number needs to search circularly, which is also
# 2.
#
#
#
# Note:
# The length of given array won't exceed 10000.# Time: O(n)
# Space: O(n)
class Solution(object):
def nextGreaterElements(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
result, stk = [0] * len(nums), []
for i in reversed(xrange(2*len(nums))):
while stk and stk[-1] <= nums[i % len(nums)]:
stk.pop()
result[i % len(nums)] = stk[-1] if stk else -1
stk.append(nums[i % len(nums)])
return result
53
rotate-image.py
# You are given an n x n 2D matrix representing an image, rotate the image by 90
# degrees (clockwise).
#
# You have to rotate the image in-place, which means you have to modify the
# input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.
#
#
# Example 1:
#
# Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
# Output: [[7,4,1],[8,5,2],[9,6,3]]
#
#
# Example 2:
#
# Input: matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
# Output: [[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
#
#
# Example 3:
#
# Input: matrix = [[1]]
# Output: [[1]]
#
#
# Example 4:
#
# Input: matrix = [[1,2],[3,4]]
# Output: [[3,1],[4,2]]
#
#
#
# Constraints:
#
#
# matrix.length == n
# matrix[i].length == n
# 1 <= n <= 20
# -1000 <= matrix[i][j] <= 1000# Time: O(n^2)
# Space: O(1)
class Solution(object):
# @param matrix, a list of lists of integers
# @return a list of lists of integers
def rotate(self, matrix):
n = len(matrix)
# anti-diagonal mirror
for i in xrange(n):
for j in xrange(n - i):
matrix[i][j], matrix[n-1-j][n-1-i] = matrix[n-1-j][n-1-i], matrix[i][j]
# horizontal mirror
for i in xrange(n / 2):
for j in xrange(n):
matrix[i][j], matrix[n-1-i][j] = matrix[n-1-i][j], matrix[i][j]
return matrix
54
# Time: O(n^2)
# Space: O(n^2)
class Solution2(object):
# @param matrix, a list of lists of integers
# @return a list of lists of integers
def rotate(self, matrix):
return [list(reversed(x)) for x in zip(*matrix)]
55
surrounded-regions.py
# Given a 2D board containing 'X' and 'O' (the letter O), capture all regions
# surrounded by 'X'.
#
# A region is captured by flipping all 'O's into 'X's in that surrounded region.
#
# Example:
#
# X X X X
# X O O X
# X X O X
# X O X X
#
#
# After running your function, the board should be:
#
# X X X X
# X X X X
# X X X X
# X O X X
#
#
# Explanation:
#
# Surrounded regions shouldn’t be on the border, which means that any 'O' on the
# border of the board are not flipped to 'X'. Any 'O' that is not on the border
# and it is not connected to an 'O' on the border will be flipped to 'X'. Two
# cells are connected if they are adjacent cells connected horizontally or
# vertically.# Time: O(m * n)
# Space: O(m + n)
import collections
class Solution(object):
def solve(self, board):
"""
:type board: List[List[str]]
:rtype: void Do not return anything, modify board in-place instead.
"""
if not board:
return
q = collections.deque()
for i in xrange(len(board)):
if board[i][0] == 'O':
board[i][0] = 'V'
q.append((i, 0))
if board[i][len(board[0])-1] == 'O':
board[i][len(board[0])-1] = 'V'
q.append((i, len(board[0])-1))
56
q.append((len(board)-1, j))
while q:
i, j = q.popleft()
for x, y in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:
if 0 <= x < len(board) and 0 <= y < len(board[0]) and \
board[x][y] == 'O':
board[x][y] = 'V'
q.append((x, y))
for i in xrange(len(board)):
for j in xrange(len(board[0])):
if board[i][j] != 'V':
board[i][j] = 'X'
else:
board[i][j] = 'O'
57
magical-string.py
# A magical string S consists of only '1' and '2' and obeys the following rules:
#
#
# The string S is magical because concatenating the number of contiguous
# occurrences of characters '1' and '2' generates the string S itself.
#
#
#
# The first few elements of string S is the following:
# S = "1221121221221121122......"
#
#
#
# If we group the consecutive '1's and '2's in S, it will be:
#
#
# 1 22 11 2 1 22 1 22 11 2 11 22 ......
#
#
# and the occurrences of '1's or '2's in each group are:
#
#
# 1 2 2 1 1 2 1 2 2 1 2 2 ......
#
#
#
# You can see that the occurrence sequence above is the S itself.
#
#
#
# Given an integer N as input, return the number of '1's in the first N number
# in the magical string S.
#
#
# Note:
# N will not exceed 100,000.
#
#
#
# Example 1:
#
# Input: 6
# Output: 3
# Explanation: The first 6 elements of magical string S is "12211" and it
# contains three 1's, so return 3.# Time: O(n)
# Space: O(logn)
import itertools
class Solution(object):
def magicalString(self, n):
"""
:type n: int
:rtype: int
"""
def gen(): # see figure 1 on page 3 of http://www.emis.ams.org/journals/JIS/VOL15/Nilsson/nilsson5.pdf
for c in 1, 2, 2:
58
yield c
for i, c in enumerate(gen()):
if i > 1:
for _ in xrange(c):
yield i % 2 + 1
59
split-array-into-consecutive-subsequences.py
# Given an array nums sorted in ascending order, return true if and only if you
# can split it into 1 or more subsequences such that each subsequence consists of
# consecutive integers and has length at least 3.
#
#
#
# Example 1:
#
# Input: [1,2,3,3,4,5]
# Output: True
# Explanation:
# You can split them into two consecutive subsequences :
# 1, 2, 3
# 3, 4, 5
#
#
#
# Example 2:
#
# Input: [1,2,3,3,4,4,5,5]
# Output: True
# Explanation:
# You can split them into two consecutive subsequences :
# 1, 2, 3, 4, 5
# 3, 4, 5
#
#
#
# Example 3:
#
# Input: [1,2,3,4,4,5]
# Output: False
#
#
#
#
# Constraints:
#
#
# 1 <= nums.length <= 10000# Time: O(n)
# Space: O(1)
class Solution(object):
def isPossible(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
pre, cur = float("-inf"), 0
cnt1, cnt2, cnt3 = 0, 0, 0
i = 0
while i < len(nums):
cnt = 0
cur = nums[i]
while i < len(nums) and cur == nums[i]:
cnt += 1
i += 1
60
if cur != pre + 1:
if cnt1 != 0 or cnt2 != 0:
return False
cnt1, cnt2, cnt3 = cnt, 0, 0
else:
if cnt < cnt1 + cnt2:
return False
cnt1, cnt2, cnt3 = max(0, cnt - (cnt1 + cnt2 + cnt3)), \
cnt1, \
cnt2 + min(cnt3, cnt - (cnt1 + cnt2))
pre = cur
return cnt1 == 0 and cnt2 == 0
61
beautiful-array.py
# Example 2:
#
# Input: 5
# Output: [3,1,2,5,4]# Time: O(n)
# Space: O(n)
class Solution(object):
def beautifulArray(self, N):
"""
:type N: int
:rtype: List[int]
"""
result = [1]
while len(result) < N:
result = [i*2 - 1 for i in result] + [i*2 for i in result]
return [i for i in result if i <= N]
62
path-sum-iii.py
# You are given a binary tree in which each node contains an integer value.
#
# Find the number of paths that sum to a given value.
#
# The path does not need to start or end at the root or a leaf, but it must go
# downwards
# (traveling only from parent nodes to child nodes).
#
# The tree has no more than 1,000 nodes and the values are in the range
# -1,000,000 to 1,000,000.
#
# Example:
# root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
#
# 10
# / \
# 5 -3
# / \ \
# 3 2 11
# / \ \
# 3 -2 1
#
# Return 3. The paths that sum to 8 are:
#
# 1. 5 -> 3
# 2. 5 -> 2 -> 1
# 3. -3 -> 11# Time: O(n)
# Space: O(h)
import collections
class Solution(object):
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: int
"""
def pathSumHelper(root, curr, sum, lookup):
if root is None:
return 0
curr += root.val
result = lookup[curr-sum] if curr-sum in lookup else 0
lookup[curr] += 1
result += pathSumHelper(root.left, curr, sum, lookup) + \
pathSumHelper(root.right, curr, sum, lookup)
lookup[curr] -= 1
if lookup[curr] == 0:
del lookup[curr]
return result
lookup = collections.defaultdict(int)
lookup[0] = 1
return pathSumHelper(root, 0, sum, lookup)
# Time: O(n^2)
63
# Space: O(h)
class Solution2(object):
def pathSum(self, root, sum):
"""
:type root: TreeNode
:type sum: int
:rtype: int
"""
def pathSumHelper(root, prev, sum):
if root is None:
return 0
if root is None:
return 0
64
design-underground-system.py
# Implement the class UndergroundSystem that supports three methods:
#
# 1. checkIn(int id, string stationName, int t)
#
#
# A customer with id card equal to id, gets in the station stationName at
# time t.
# A customer can only be checked into one place at a time.
#
#
# 2. checkOut(int id, string stationName, int t)
#
#
# A customer with id card equal to id, gets out from the station
# stationName at time t.
#
#
# 3. getAverageTime(string startStation, string endStation)
#
#
# Returns the average time to travel between the startStation and the
# endStation.
# The average time is computed from all the previous traveling from
# startStation to endStation that happened directly.
# Call to getAverageTime is always valid.
#
#
# You can assume all calls to checkIn and checkOut methods are consistent. That
# is, if a customer gets in at time t1 at some station, then it gets out at time
# t2 with t2 > t1. All events happen in chronological order.
#
#
# Example 1:
#
# Input
# ["UndergroundSystem","checkIn","checkIn","checkIn","checkOut","checkOut","chec
# kOut","getAverageTime","getAverageTime","checkIn","getAverageTime","checkOut","g
# etAverageTime"]
# [[],[45,"Leyton",3],[32,"Paradise",8],[27,"Leyton",10],[45,"Waterloo",15],[27,
# "Waterloo",20],[32,"Cambridge",22],["Paradise","Cambridge"],["Leyton","Waterloo"
# ],[10,"Leyton",24],["Leyton","Waterloo"],[10,"Waterloo",38],["Leyton","Waterloo"
# ]]
#
# Output
# [null,null,null,null,null,null,null,14.00000,11.00000,null,11.00000,null,12.00
# 000]
#
# Explanation
# UndergroundSystem undergroundSystem = new UndergroundSystem();
# undergroundSystem.checkIn(45, "Leyton", 3);
# undergroundSystem.checkIn(32, "Paradise", 8);
# undergroundSystem.checkIn(27, "Leyton", 10);
# undergroundSystem.checkOut(45, "Waterloo", 15);
# undergroundSystem.checkOut(27, "Waterloo", 20);
# undergroundSystem.checkOut(32, "Cambridge", 22);
# undergroundSystem.getAverageTime("Paradise", "Cambridge"); // return
# 14.00000. There was only one travel from "Paradise" (at time 8) to "Cambridge"
# (at time 22)
65
# undergroundSystem.getAverageTime("Leyton", "Waterloo"); // return
# 11.00000. There were two travels from "Leyton" to "Waterloo", a customer with
# id=45 from time=3 to time=15 and a customer with id=27 from time=10 to time=20.
# So the average time is ( (15-3) + (20-10) ) / 2 = 11.00000
# undergroundSystem.checkIn(10, "Leyton", 24);
# undergroundSystem.getAverageTime("Leyton", "Waterloo"); // return
# 11.00000
# undergroundSystem.checkOut(10, "Waterloo", 38);
# undergroundSystem.getAverageTime("Leyton", "Waterloo"); // return
# 12.00000
#
#
# Example 2:
#
# Input
# ["UndergroundSystem","checkIn","checkOut","getAverageTime","checkIn","checkOut
# ","getAverageTime","checkIn","checkOut","getAverageTime"]
# [[],[10,"Leyton",3],[10,"Paradise",8],["Leyton","Paradise"],[5,"Leyton",10],[5
# ,"Paradise",16],["Leyton","Paradise"],[2,"Leyton",21],[2,"Paradise",30],["Leyton
# ","Paradise"]]
#
# Output
# [null,null,null,5.00000,null,null,5.50000,null,null,6.66667]
#
# Explanation
# UndergroundSystem undergroundSystem = new UndergroundSystem();
# undergroundSystem.checkIn(10, "Leyton", 3);
# undergroundSystem.checkOut(10, "Paradise", 8);
# undergroundSystem.getAverageTime("Leyton", "Paradise"); // return 5.00000
# undergroundSystem.checkIn(5, "Leyton", 10);
# undergroundSystem.checkOut(5, "Paradise", 16);
# undergroundSystem.getAverageTime("Leyton", "Paradise"); // return 5.50000
# undergroundSystem.checkIn(2, "Leyton", 21);
# undergroundSystem.checkOut(2, "Paradise", 30);
# undergroundSystem.getAverageTime("Leyton", "Paradise"); // return 6.66667
#
#
#
# Constraints:
#
#
# There will be at most 20000 operations.
# 1 <= id, t <= 10^6
# All strings consist of uppercase, lowercase English letters and digits.
# 1 <= stationName.length <= 10
# Answers within 10^-5 of the actual value will be accepted as correct.# Time: ctor: O(1)
# checkin: O(1)
# checkout: O(1)
# getaverage: O(1)
# Space: O(n)
import collections
class UndergroundSystem(object):
def __init__(self):
self.__live = {}
self.__statistics = collections.defaultdict(lambda: [0, 0])
66
def checkIn(self, id, stationName, t):
"""
:type id: int
:type stationName: str
:type t: int
:rtype: None
"""
self.__live[id] = (stationName, t)
67
find-all-duplicates-in-an-array.py
# Given an array of integers, 1 a[i] n (n = size of array), some elements
# appear twice and others appear once.
#
# Find all the elements that appear twice in this array.
#
# Could you do it without extra space and in O(n) runtime?
#
# Example:
#
# Input:
# [4,3,2,7,8,2,3,1]
#
# Output:
# [2,3]# Time: O(n)
# Space: O(1)
class Solution(object):
def findDuplicates(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
result = []
for i in nums:
if nums[abs(i)-1] < 0:
result.append(abs(i))
else:
nums[abs(i)-1] *= -1
return result
# Time: O(n)
# Space: O(1)
class Solution2(object):
def findDuplicates(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
result = []
i = 0
while i < len(nums):
if nums[i] != nums[nums[i]-1]:
nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]
else:
i += 1
for i in xrange(len(nums)):
if i != nums[i]-1:
result.append(nums[i])
return result
# Time: O(n)
# Space: O(n), this doesn't satisfy the question
from collections import Counter
class Solution3(object):
def findDuplicates(self, nums):
68
"""
:type nums: List[int]
:rtype: List[int]
"""
return [elem for elem, count in Counter(nums).items() if count == 2]
69
zigzag-conversion.py
# The string "PAYPALISHIRING" is written in a zigzag pattern on a given number
# of rows like this: (you may want to display this pattern in a fixed font for
# better legibility)
#
# P A H N
# A P L S I I G
# Y I R
#
#
# And then read line by line: "PAHNAPLSIIGYIR"
#
# Write the code that will take a string and make this conversion given a number
# of rows:
#
# string convert(string s, int numRows);
#
# Example 1:
#
# Input: s = "PAYPALISHIRING", numRows = 3
# Output: "PAHNAPLSIIGYIR"
#
#
# Example 2:
#
# Input: s = "PAYPALISHIRING", numRows = 4
# Output: "PINALSIGYAHRPI"
# Explanation:
#
# P I N
# A L S I G
# Y A H R
# P I# Time: O(n)
# Space: O(1)
class Solution(object):
def convert(self, s, numRows):
"""
:type s: str
:type numRows: int
:rtype: str
"""
if numRows == 1:
return s
step, zigzag = 2 * numRows - 2, ""
for i in xrange(numRows):
for j in xrange(i, len(s), step):
zigzag += s[j]
if 0 < i < numRows - 1 and j + step - 2 * i < len(s):
zigzag += s[j + step - 2 * i]
return zigzag
70
number-of-dice-rolls-with-target-sum.py
# You have d dice, and each die has f faces numbered 1, 2, ..., f.
#
# Return the number of possible ways (out of fd total ways) modulo 10^9 + 7 to
# roll the dice so the sum of the face up numbers equals target.
#
#
# Example 1:
#
# Input: d = 1, f = 6, target = 3
# Output: 1
# Explanation:
# You throw one die with 6 faces. There is only one way to get a sum of 3.
#
#
# Example 2:
#
# Input: d = 2, f = 6, target = 7
# Output: 6
# Explanation:
# You throw two dice, each with 6 faces. There are 6 ways to get a sum of 7:
# 1+6, 2+5, 3+4, 4+3, 5+2, 6+1.
#
#
# Example 3:
#
# Input: d = 2, f = 5, target = 10
# Output: 1
# Explanation:
# You throw two dice, each with 5 faces. There is only one way to get a sum of
# 10: 5+5.
#
#
# Example 4:
#
# Input: d = 1, f = 2, target = 3
# Output: 0
# Explanation:
# You throw one die with 2 faces. There is no way to get a sum of 3.
#
#
# Example 5:
#
# Input: d = 30, f = 30, target = 500
# Output: 222616187
# Explanation:
# The answer must be returned modulo 10^9 + 7.
#
#
#
# Constraints:
#
#
# 1 <= d, f <= 30
# 1 <= target <= 1000# Time: O(d * f * t)
# Space: O(t)
class Solution(object):
def numRollsToTarget(self, d, f, target):
71
"""
:type d: int
:type f: int
:type target: int
:rtype: int
"""
MOD = 10**9+7
dp = [[0 for _ in xrange(target+1)] for _ in xrange(2)]
dp[0][0] = 1
for i in xrange(1, d+1):
dp[i%2] = [0 for _ in xrange(target+1)]
for k in xrange(1, f+1):
for j in xrange(k, target+1):
dp[i%2][j] = (dp[i%2][j] + dp[(i-1)%2][j-k]) % MOD
return dp[d%2][target] % MOD
72
knight-dialer.py
# The chess knight has a unique movement, it may move two squares vertically and
# one square horizontally, or two squares horizontally and one square vertically
# (with both forming the shape of an L). The possible movements of chess knight
# are shown in this diagaram:
#
# A chess knight can move as indicated in the chess diagram below:
#
# We have a chess knight and a phone pad as shown below, the knight can only
# stand on a numeric cell (i.e. blue cell).
#
# Given an integer n, return how many distinct phone numbers of length n we can
# dial.
#
# You are allowed to place the knight on any numeric cell initially and then you
# should perform n - 1 jumps to dial a number of length n. All jumps should be
# valid knight jumps.
#
# As the answer may be very large, return the answer modulo 109 + 7.
#
#
# Example 1:
#
# Input: n = 1
# Output: 10
# Explanation: We need to dial a number of length 1, so placing the knight over
# any numeric cell of the 10 cells is sufficient.
#
#
# Example 2:
#
# Input: n = 2
# Output: 20
# Explanation: All the valid number we can dial are [04, 06, 16, 18, 27, 29, 34,
# 38, 40, 43, 49, 60, 61, 67, 72, 76, 81, 83, 92, 94]
#
#
# Example 3:
#
# Input: n = 3
# Output: 46
#
#
# Example 4:
#
# Input: n = 4
# Output: 104
#
#
# Example 5:
#
# Input: n = 3131
# Output: 136006598
# Explanation: Please take care of the mod.
#
#
#
# Constraints:
#
73
#
# 1 <= n <= 5000# Time: O(logn)
# Space: O(1)
import itertools
class Solution(object):
def knightDialer(self, N):
"""
:type N: int
:rtype: int
"""
def matrix_expo(A, K):
result = [[int(i==j) for j in xrange(len(A))] \
for i in xrange(len(A))]
while K:
if K % 2:
result = matrix_mult(result, A)
A = matrix_mult(A, A)
K /= 2
return result
M = 10**9 + 7
T = [[0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
[1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0]]
return sum(map(sum, matrix_expo(T, N-1))) % M
# Time: O(n)
# Space: O(1)
class Solution2(object):
def knightDialer(self, N):
"""
:type N: int
:rtype: int
"""
M = 10**9 + 7
moves = [[4, 6], [6, 8], [7, 9], [4, 8], [3, 9, 0], [],
[1, 7, 0], [2, 6], [1, 3], [2, 4]]
74
dp[(i+1) % 2][nei] %= M
return sum(dp[(N-1) % 2]) % M
75
maximum-difference-between-node-and-ancestor.py
# Given the root of a binary tree, find the maximum value V for which there
# exists different nodes A and B where V = |A.val - B.val| and A is an ancestor of
# B.
#
# (A node A is an ancestor of B if either: any child of A is equal to B, or any
# child of A is an ancestor of B.)
#
#
#
# Example 1:
#
#
#
# Input: [8,3,10,1,6,null,14,null,null,4,7,13]
# Output: 7
# Explanation:
# We have various ancestor-node differences, some of which are given below :
# |8 - 3| = 5
# |3 - 7| = 4
# |8 - 1| = 7
# |10 - 13| = 3
# Among all possible differences, the maximum value of 7 is obtained by |8 - 1|
# = 7.
#
#
#
#
# Note:
#
#
# The number of nodes in the tree is between 2 and 5000.
# Each node will have value between 0 and 100000.# Time: O(n)
# Space: O(h)
76
stack.append((node.left, mx, mn))
stack.append((node.right, mx, mn))
return result
# Time: O(n)
# Space: O(h)
# recursive solution
class Solution2(object):
def maxAncestorDiff(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def maxAncestorDiffHelper(node, mx, mn):
if not node:
return 0
result = max(mx-node.val, node.val-mn)
mx = max(mx, node.val)
mn = min(mn, node.val)
result = max(result, maxAncestorDiffHelper(node.left, mx, mn))
result = max(result, maxAncestorDiffHelper(node.right, mx, mn))
return result
77
maximum-product-of-word-lengths.py
# Given a string array words, find the maximum value of length(word[i]) *
# length(word[j]) where the two words do not share common letters. You may assume
# that each word will contain only lower case letters. If no such two words exist,
# return 0.
#
# Example 1:
#
# Input: ["abcw","baz","foo","bar","xtfn","abcdef"]
# Output: 16
# Explanation: The two words can be "abcw", "xtfn".
#
# Example 2:
#
# Input: ["a","ab","abc","d","cd","bcd","abcd"]
# Output: 4
# Explanation: The two words can be "ab", "cd".
#
# Example 3:
#
# Input: ["a","aa","aaa","aaaa"]
# Output: 0
# Explanation: No such pair of words.
#
#
#
# Constraints:
#
#
# 0 <= words.length <= 10^3
# 0 <= words[i].length <= 10^3
# words[i] consists only of lowercase English letters.# Time: O(n) ~ O(n^2)
# Space: O(n)
class Solution(object):
def maxProduct(self, words):
"""
:type words: List[str]
:rtype: int
"""
def counting_sort(words):
k = 1000 # k is max length of words in the dictionary
buckets = [[] for _ in xrange(k)]
for word in words:
buckets[len(word)].append(word)
res = []
for i in reversed(xrange(k)):
if buckets[i]:
res += buckets[i]
return res
words = counting_sort(words)
bits = [0] * len(words)
for i, word in enumerate(words):
for c in word:
bits[i] |= (1 << (ord(c) - ord('a')))
max_product = 0
for i in xrange(len(words) - 1):
78
if len(words[i]) ** 2 <= max_product:
break
for j in xrange(i + 1, len(words)):
if len(words[i]) * len(words[j]) <= max_product:
break
if not (bits[i] & bits[j]):
max_product = len(words[i]) * len(words[j])
return max_product
max_product = 0
for i in xrange(len(words) - 1):
if len(words[i]) ** 2 <= max_product:
break
for j in xrange(i + 1, len(words)):
if len(words[i]) * len(words[j]) <= max_product:
break
if not (bits[i] & bits[j]):
max_product = len(words[i]) * len(words[j])
return max_product
79
remove-duplicates-from-sorted-list-ii.py
# Given a sorted linked list, delete all nodes that have duplicate numbers,
# leaving only distinct numbers from the original list.
#
# Return the linked list sorted as well.
#
# Example 1:
#
# Input: 1->2->3->3->4->4->5
# Output: 1->2->5
#
#
# Example 2:
#
# Input: 1->1->1->2->3
# Output: 2->3# Time: O(n)
# Space: O(1)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self is None:
return "Nil"
else:
return "{} -> {}".format(self.val, repr(self.next))
class Solution(object):
def deleteDuplicates(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
dummy = ListNode(0)
pre, cur = dummy, head
while cur:
if cur.next and cur.next.val == cur.val:
val = cur.val
while cur and cur.val == val:
cur = cur.next
pre.next = cur
else:
pre.next = cur
pre = cur
cur = cur.next
return dummy.next
80
longest-arithmetic-subsequence-of-given-difference.py
# Given an integer array arr and an integer difference, return the length of the
# longest subsequence in arr which is an arithmetic sequence such that the
# difference between adjacent elements in the subsequence equals difference.
#
#
# Example 1:
#
# Input: arr = [1,2,3,4], difference = 1
# Output: 4
# Explanation: The longest arithmetic subsequence is [1,2,3,4].
#
# Example 2:
#
# Input: arr = [1,3,5,7], difference = 1
# Output: 1
# Explanation: The longest arithmetic subsequence is any single element.
#
#
# Example 3:
#
# Input: arr = [1,5,7,8,5,3,4,2,1], difference = -2
# Output: 4
# Explanation: The longest arithmetic subsequence is [7,5,3,1].
#
#
#
# Constraints:
#
#
# 1 <= arr.length <= 10^5
# -10^4 <= arr[i], difference <= 10^4# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def longestSubsequence(self, arr, difference):
"""
:type arr: List[int]
:type difference: int
:rtype: int
"""
result = 1
lookup = collections.defaultdict(int)
for i in xrange(len(arr)):
lookup[arr[i]] = lookup[arr[i]-difference] + 1
result = max(result, lookup[arr[i]])
return result
81
sum-of-two-integers.py
# Example 2:
#
# Input: a = -2, b = 3
# Output: 1# Time: O(1)
# Space: O(1)
class Solution(object):
def getSum(self, a, b):
"""
:type a: int
:type b: int
:rtype: int
"""
bit_length = 32
neg_bit, mask = (1 << bit_length) >> 1, ~(~0 << bit_length)
while b:
carry = a & b
a ^= b
a = (a | ~mask) if (a & neg_bit) else (a & mask)
b = carry << 1
b = (b | ~mask) if (b & neg_bit) else (b & mask)
return a
82
y >>= 1
x <<= 1
return self.getSum(~ans, 1) if isNeg else ans
83
partition-equal-subset-sum.py
# Given a non-empty array containing only positive integers, find if the array
# can be partitioned into two subsets such that the sum of elements in both
# subsets is equal.
#
# Note:
#
#
# Each of the array element will not exceed 100.
# The array size will not exceed 200.
#
#
#
#
# Example 1:
#
# Input: [1, 5, 11, 5]
#
# Output: true
#
# Explanation: The array can be partitioned as [1, 5, 5] and [11].
#
#
#
#
# Example 2:
#
# Input: [1, 2, 3, 5]
#
# Output: false
#
# Explanation: The array cannot be partitioned into equal sum subsets.# Time: O(n * s), s is the sum of nums
# Space: O(s)
class Solution(object):
def canPartition(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
s = sum(nums)
if s % 2:
return False
dp = [False] * (s/2 + 1)
dp[0] = True
for num in nums:
for i in reversed(xrange(1, len(dp))):
if num <= i:
dp[i] = dp[i] or dp[i - num]
return dp[-1]
84
moving-stones-until-consecutive-ii.py
# Example 2:
#
# Input: [6,5,4,3,10]
# Output: [2,3]
# We can move 3 -> 8 then 10 -> 7 to finish the game.
# Or, we can move 3 -> 7, 4 -> 8, 5 -> 9 to finish the game.
# Notice we cannot move 10 -> 2 to finish the game, because that would be an
# illegal move.
#
#
#
# Example 3:
#
# Input: [100,101,104,102,103]
# Output: [0,0]# Time: O(nlogn)
# Space: O(1)
class Solution(object):
def numMovesStonesII(self, stones):
"""
:type stones: List[int]
:rtype: List[int]
"""
stones.sort()
left, min_moves = 0, float("inf")
max_moves = max(stones[-1]-stones[1], stones[-2]-stones[0]) - (len(stones)-2)
for right in xrange(len(stones)):
while stones[right]-stones[left]+1 > len(stones): # find window size <= len(stones)
left += 1
if len(stones)-(right-left+1) == 1 and stones[right]-stones[left]+1 == len(stones)-1:
min_moves = min(min_moves, 2) # case (1, 2, 3, 4), 7
else:
min_moves = min(min_moves, len(stones)-(right-left+1)) # move stones not in this window
return [min_moves, max_moves]
85
corporate-flight-bookings.py
# There are n flights, and they are labeled from 1 to n.
#
# We have a list of flight bookings. The i-th booking bookings[i] = [i, j,
# k] means that we booked k seats from flights labeled i to j inclusive.
#
# Return an array answer of length n, representing the number of seats booked on
# each flight in order of their label.
#
#
# Example 1:
#
# Input: bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5
# Output: [10,55,45,25,25]
#
#
#
# Constraints:
#
#
# 1 <= bookings.length <= 20000
# 1 <= bookings[i][0] <= bookings[i][1] <= n <= 20000
# 1 <= bookings[i][2] <= 10000# Time: O(n)
# Space: O(1)
class Solution(object):
def corpFlightBookings(self, bookings, n):
"""
:type bookings: List[List[int]]
:type n: int
:rtype: List[int]
"""
result = [0]*(n+1)
for i, j, k in bookings:
result[i-1] += k
result[j] -= k
for i in xrange(1, len(result)):
result[i] += result[i-1]
result.pop()
return result
86
print-binary-tree.py
# Print a binary tree in an m*n 2D string array following these rules:
#
#
# The row number m should be equal to the height of the given binary tree.
# The column number n should always be an odd number.
# The root node's value (in string format) should be put in the exactly middle
# of the first row it can be put. The column and the row where the root node
# belongs will separate the rest space into two parts (left-bottom part and right-
# bottom part). You should print the left subtree in the left-bottom part and
# print the right subtree in the right-bottom part. The left-bottom part and the
# right-bottom part should have the same size. Even if one subtree is none while
# the other is not, you don't need to print anything for the none subtree but
# still need to leave the space as large as that for the other subtree. However,
# if two subtrees are none, then you don't need to leave space for both of them.
# Each unused space should contain an empty string "".
# Print the subtrees following the same rules.
#
#
# Example 1:
#
# Input:
# 1
# /
# 2
# Output:
# [["", "1", ""],
# ["2", "", ""]]
#
#
#
#
# Example 2:
#
# Input:
# 1
# / \
# 2 3
# \
# 4
# Output:
# [["", "", "", "1", "", "", ""],
# ["", "2", "", "", "", "3", ""],
# ["", "", "4", "", "", "", ""]]
#
#
#
# Example 3:
#
# Input:
# 1
# / \
# 2 5
# /
# 3
# /
# 4
# Output:
#
87
# [["", "", "", "", "", "", "", "1", "", "", "", "", "", "", ""]
# ["", "", "", "2", "", "", "", "", "", "", "", "5", "", "", ""]
# ["", "3", "", "", "", "", "", "", "", "", "", "", "", "", ""]
# ["4", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]]
#
#
#
# Note:
# The height of binary tree is in the range of [1, 10].# Time: O(h * 2^h)
# Space: O(h * 2^h)
class Solution(object):
def printTree(self, root):
"""
:type root: TreeNode
:rtype: List[List[str]]
"""
def getWidth(root):
if not root:
return 0
return 2 * max(getWidth(root.left), getWidth(root.right)) + 1
def getHeight(root):
if not root:
return 0
return max(getHeight(root.left), getHeight(root.right)) + 1
h, w = getHeight(root), getWidth(root)
result = [[""] * w for _ in xrange(h)]
preorderTraversal(root, 0, 0, w-1, result)
return result
88
linked-list-random-node.py
# Given a singly linked list, return a random node's value from the linked list.
# Each node must have the same probability of being chosen.
#
# Follow up:
#
# What if the linked list is extremely large and its length is unknown to you?
# Could you solve this efficiently without using extra space?
#
#
# Example:
# // Init a singly linked list [1,2,3].
# ListNode head = new ListNode(1);
# head.next = new ListNode(2);
# head.next.next = new ListNode(3);
# Solution solution = new Solution(head);
#
# // getRandom() should return either 1, 2, or 3 randomly. Each element should
# have equal probability of returning.
# solution.getRandom();# Time: O(n)
# Space: O(1)
class Solution(object):
89
swap-for-longest-repeated-character-substring.py
# Given a string text, we are allowed to swap two of the characters in the
# string. Find the length of the longest substring with repeated characters.
#
#
# Example 1:
#
# Input: text = "ababa"
# Output: 3
# Explanation: We can swap the first 'b' with the last 'a', or the last 'b' with
# the first 'a'. Then, the longest repeated character substring is "aaa", which
# its length is 3.
#
#
# Example 2:
#
# Input: text = "aaabaaa"
# Output: 6
# Explanation: Swap 'b' with the last 'a' (or the first 'a'), and we get longest
# repeated character substring "aaaaaa", which its length is 6.
#
#
# Example 3:
#
# Input: text = "aaabbaaa"
# Output: 4
#
#
# Example 4:
#
# Input: text = "aaaaa"
# Output: 5
# Explanation: No need to swap, longest repeated character substring is "aaaaa",
# length is 5.
#
#
# Example 5:
#
# Input: text = "abcdef"
# Output: 1
#
#
#
# Constraints:
#
#
# 1 <= text.length <= 20000
# text consist of lowercase English characters only.# Time: O(n)
# Space: O(1)
import collections
class Solution(object):
def maxRepOpt1(self, text):
"""
:type text: str
:rtype: int
"""
90
K = 1
result = 0
total_count, count = collections.Counter(), collections.Counter()
left, max_count = 0, 0
for i in xrange(len(text)):
total_count[text[i]] += 1
count[text[i]] += 1
max_count = max(max_count, count[text[i]])
if i-left+1 - max_count > K:
count[text[left]] -= 1
left += 1
result = max(result, min(i-left+1, total_count[text[i]]))
return result
# Time: O(n)
# Space: O(n)
import itertools
class Solution2(object):
def maxRepOpt1(self, text):
"""
:type text: str
:rtype: int
"""
A = [[c, len(list(group))] for c, group in itertools.groupby(text)]
total_count = collections.Counter(text)
result = max(min(l+1, total_count[c]) for c, l in A)
for i in xrange(1, len(A)-1):
if A[i-1][0] == A[i+1][0] and A[i][1] == 1:
result = max(result, min(A[i-1][1] + 1 + A[i+1][1], total_count[A[i+1][0]]))
return result
91
maximum-sum-of-two-non-overlapping-subarrays.py
# Example 2:
#
# Input: A = [3,8,1,3,2,1,8,9,0], L = 3, M = 2
# Output: 29
# Explanation: One choice of subarrays is [3,8,1] with length 3, and [8,9] with
# length 2.
#
#
#
# Example 3:
#
# Input: A = [2,1,5,6,0,9,5,0,3,8], L = 4, M = 3
# Output: 31
# Explanation: One choice of subarrays is [5,6,0,9] with length 4, and [3,8]
# with length 3.
#
#
#
#
# Note:
#
#
# L
>= 1
# M
>= 1
# L
+ M <= A.length <= 1000
# 0
<= A[i] <= 1000# Time: O(n)
# Space: O(1)
class Solution(object):
def maxSumTwoNoOverlap(self, A, L, M):
"""
:type A: List[int]
:type L: int
:type M: int
:rtype: int
"""
for i in xrange(1, len(A)):
A[i] += A[i-1]
result, L_max, M_max = A[L+M-1], A[L-1], A[M-1]
for i in xrange(L+M, len(A)):
L_max = max(L_max, A[i-M] - A[i-L-M])
M_max = max(M_max, A[i-L] - A[i-L-M])
result = max(result,
L_max + A[i] - A[i-M],
M_max + A[i] - A[i-L])
return result
92
binary-tree-level-order-traversal.py
# Given a binary tree, return the level order traversal of its nodes' values.
# (ie, from left to right, level by level).
#
#
# For example:
#
# Given binary tree [3,9,20,null,null,15,7],
#
# 3
# / \
# 9 20
# / \
# 15 7
#
#
#
# return its level order traversal as:
#
# [
# [3],
# [9,20],
# [15,7]
# ]# Time: O(n)
# Space: O(n)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
# @param root, a tree node
# @return a list of lists of integers
def levelOrder(self, root):
if root is None:
return []
result, current = [], [root]
while current:
next_level, vals = [], []
for node in current:
vals.append(node.val)
if node.left:
next_level.append(node.left)
if node.right:
next_level.append(node.right)
current = next_level
result.append(vals)
return result
93
construct-binary-search-tree-from-preorder-traversal.py
# Return the root node of a binary search tree that matches the given preorder
# traversal.
#
# (Recall that a binary search tree is a binary tree where for every node, any
# descendant of node.left has a value < node.val, and any descendant of node.right
# has a value > node.val. Also recall that a preorder traversal displays the
# value of the node first, then traverses node.left, then traverses node.right.)
#
# It's guaranteed that for the given test cases there is always possible to find
# a binary search tree with the given requirements.
#
# Example 1:
#
# Input: [8,5,1,7,10,12]
# Output: [8,5,10,1,7,null,12]
#
#
#
#
# Constraints:
#
#
# 1 <= preorder.length <= 100
# 1 <= preorder[i] <= 10^8
# The values of preorder are distinct.# Time: O(n)
# Space: O(h)
class Solution(object):
def bstFromPreorder(self, preorder):
"""
:type preorder: List[int]
:rtype: TreeNode
"""
def bstFromPreorderHelper(preorder, left, right, index):
if index[0] == len(preorder) or \
preorder[index[0]] < left or \
preorder[index[0]] > right:
return None
root = TreeNode(preorder[index[0]])
index[0] += 1
root.left = bstFromPreorderHelper(preorder, left, root.val, index)
root.right = bstFromPreorderHelper(preorder, root.val, right, index)
return root
94
minimum-number-of-arrows-to-burst-balloons.py
# There are a number of spherical balloons spread in two-dimensional space. For
# each balloon, provided input is the start and end coordinates of the horizontal
# diameter. Since it's horizontal, y-coordinates don't matter and hence the
# x-coordinates of start and end of the diameter suffice. Start is always smaller
# than end. There will be at most 104 balloons.
#
# An arrow can be shot up exactly vertically from different points along the
# x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart
# x xend. There is no limit to the number of arrows that can be shot. An arrow
# once shot keeps travelling up infinitely. The problem is to find the minimum
# number of arrows that must be shot to burst all balloons.
#
# Example:
#
# Input:
# [[10,16], [2,8], [1,6], [7,12]]
#
# Output:
# 2
#
# Explanation:
# One way is to shoot one arrow for example at x = 6 (bursting the balloons
# [2,8] and [1,6]) and another arrow at x = 11 (bursting the other two balloons).# Time: O(nlogn)
# Space: O(1)
class Solution(object):
def findMinArrowShots(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
if not points:
return 0
points.sort()
result = 0
i = 0
while i < len(points):
j = i + 1
right_bound = points[i][1]
while j < len(points) and points[j][0] <= right_bound:
right_bound = min(right_bound, points[j][1])
j += 1
result += 1
i = j
return result
95
search-a-2d-matrix-ii.py
# Write an efficient algorithm that searches for a value in an m x n matrix.
# This matrix has the following properties:
#
#
# Integers in each row are sorted in ascending from left to right.
# Integers in each column are sorted in ascending from top to bottom.
#
#
# Example:
#
# Consider the following matrix:
#
# [
# [1, 4, 7, 11, 15],
# [2, 5, 8, 12, 19],
# [3, 6, 9, 16, 22],
# [10, 13, 14, 17, 24],
# [18, 21, 23, 26, 30]
# ]
#
#
# Given target = 5, return true.
#
# Given target = 20, return false.# Time: O(m + n)
# Space: O(1)
class Solution(object):
# @param {integer[][]} matrix
# @param {integer} target
# @return {boolean}
def searchMatrix(self, matrix, target):
m = len(matrix)
if m == 0:
return False
n = len(matrix[0])
if n == 0:
return False
i, j = 0, n - 1
while i < m and j >= 0:
if matrix[i][j] == target:
return True
elif matrix[i][j] > target:
j -= 1
else:
i += 1
return False
96
mini-parser.py
# Given a nested list of integers represented as a string, implement a parser to
# deserialize it.
#
# Each element is either an integer, or a list -- whose elements may also be
# integers or other lists.
#
# Note: You may assume that the string is well-formed:
#
#
# String is non-empty.
# String does not contain white spaces.
# String contains only digits 0-9, [, - ,, ].
#
#
#
#
# Example 1:
#
# Given s = "324",
#
# You should return a NestedInteger object which contains a single integer 324.
#
#
#
#
# Example 2:
#
# Given s = "[123,[456,[789]]]",
#
# Return a NestedInteger object containing a nested list with 2 elements:
#
# 1. An integer containing value 123.
# 2. A nested list containing two elements:
# i. An integer containing value 456.
# ii. A nested list with one element:
# a. An integer containing value 789.# Time: O(n)
# Space: O(h)
class NestedInteger(object):
def __init__(self, value=None):
"""
If value is not specified, initializes an empty list.
Otherwise initializes a single integer equal to value.
"""
def isInteger(self):
"""
@return True if this NestedInteger holds a single integer, rather than a nested list.
:rtype bool
"""
97
"""
Set this NestedInteger to hold a single integer equal to value.
:rtype void
"""
def getInteger(self):
"""
@return the single integer that this NestedInteger holds, if it holds a single integer
Return None if this NestedInteger holds a nested list
:rtype int
"""
def getList(self):
"""
@return the nested list that this NestedInteger holds, if it holds a nested list
Return None if this NestedInteger holds a single integer
:rtype List[NestedInteger]
"""
class Solution(object):
def deserialize(self, s):
if not s:
return NestedInteger()
if s[0] != '[':
return NestedInteger(int(s))
stk = []
i = 0
for j in xrange(len(s)):
if s[j] == '[':
stk += NestedInteger(),
i = j+1
elif s[j] in ',]':
if s[j-1].isdigit():
stk[-1].add(NestedInteger(int(s[i:j])))
if s[j] == ']' and len(stk) > 1:
cur = stk[-1]
stk.pop()
stk[-1].add(cur)
i = j+1
return stk[-1]
98
angle-between-hands-of-a-clock.py
# Given two numbers, hour and minutes. Return the smaller angle (in degrees)
# formed between the hour and the minute hand.
#
#
# Example 1:
#
#
#
# Input: hour = 12, minutes = 30
# Output: 165
#
#
# Example 2:
#
#
#
# Input: hour = 3, minutes = 30
# Output: 75
#
#
# Example 3:
#
#
#
# Input: hour = 3, minutes = 15
# Output: 7.5
#
#
# Example 4:
#
# Input: hour = 4, minutes = 50
# Output: 155
#
#
# Example 5:
#
# Input: hour = 12, minutes = 0
# Output: 0
#
#
#
# Constraints:
#
#
# 1 <= hour <= 12
# 0 <= minutes <= 59
# Answers within 10^-5 of the actual value will be accepted as correct.# Time: O(1)
# Space: O(1)
class Solution(object):
def angleClock(self, hour, minutes):
"""
:type hour: int
:type minutes: int
:rtype: float
"""
angle1 = (hour % 12 * 60.0 + minutes) / 720.0
angle2 = minutes / 60.0
99
diff = abs(angle1-angle2)
return min(diff, 1.0-diff) * 360.0
100
out-of-boundary-paths.py
# There is an m by n grid with a ball. Given the start coordinate (i,j) of the
# ball, you can move the ball to adjacent cell or cross the grid boundary in four
# directions (up, down, left, right). However, you can at most move N times. Find
# out the number of paths to move the ball out of grid boundary. The answer may be
# very large, return it after mod 109 + 7.
#
#
#
# Example 1:
#
# Input: m = 2, n = 2, N = 2, i = 0, j = 0
# Output: 6
# Explanation:
#
#
#
# Example 2:
#
# Input: m = 1, n = 3, N = 3, i = 0, j = 1
# Output: 12
# Explanation:
#
#
#
#
#
# Note:
#
#
# Once you move the ball out of boundary, you cannot move it back.
# The length and height of the grid is in range [1,50].
# N is in range [0,50].# Time: O(N * m * n)
# Space: O(m * n)
class Solution(object):
def findPaths(self, m, n, N, x, y):
"""
:type m: int
:type n: int
:type N: int
:type x: int
:type y: int
:rtype: int
"""
M = 1000000000 + 7
dp = [[[0 for _ in xrange(n)] for _ in xrange(m)] for _ in xrange(2)]
for moves in xrange(N):
for i in xrange(m):
for j in xrange(n):
dp[(moves + 1) % 2][i][j] = (((1 if (i == 0) else dp[moves % 2][i - 1][j]) + \
(1 if (i == m - 1) else dp[moves % 2][i + 1][j])) % M + \
((1 if (j == 0) else dp[moves % 2][i][j - 1]) + \
(1 if (j == n - 1) else dp[moves % 2][i][j + 1])) % M) % M
return dp[N % 2][x][y]
101
battleships-in-a-board.py
# Given an 2D board, count how many battleships are in it. The battleships are
# represented with 'X's, empty slots are represented with '.'s. You may assume the
# following rules:
#
#
# You receive a valid board, made of only battleships or empty slots.
# Battleships can only be placed horizontally or vertically. In other words,
# they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1
# column), where N can be of any size.
# At least one horizontal or vertical cell separates between two battleships -
# there are no adjacent battleships.
#
#
# Example:
#
# X..X
# ...X
# ...X
#
# In the above board there are 2 battleships.
#
# Invalid Example:
#
# ...X
# XXXX
# ...X
#
# This is an invalid board that you will not receive - as battleships will
# always have a cell separating between them.
#
# Follow up:
# Could you do it in one-pass, using only O(1) extra memory and without
# modifying the value of the board?# Time: O(m * n)
# Space: O(1)
class Solution(object):
def countBattleships(self, board):
"""
:type board: List[List[str]]
:rtype: int
"""
if not board or not board[0]:
return 0
cnt = 0
for i in xrange(len(board)):
for j in xrange(len(board[0])):
cnt += int(board[i][j] == 'X' and
(i == 0 or board[i - 1][j] != 'X') and
(j == 0 or board[i][j - 1] != 'X'))
return cnt
102
subarray-sum-equals-k.py
# Given an array of integers and an integer k, you need to find the total number
# of continuous subarrays whose sum equals to k.
#
# Example 1:
#
# Input:nums = [1,1,1], k = 2
# Output: 2
#
#
#
# Constraints:
#
#
# The length of the array is in range [1, 20,000].
# The range of numbers in the array is [-1000, 1000] and the range of the
# integer k is [-1e7, 1e7].# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def subarraySum(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
result = 0
accumulated_sum = 0
lookup = collections.defaultdict(int)
lookup[0] += 1
for num in nums:
accumulated_sum += num
result += lookup[accumulated_sum - k]
lookup[accumulated_sum] += 1
return result
103
set-matrix-zeroes.py
# Given an m x n matrix. If an element is 0, set its entire row and column to 0.
# Do it in-place.
#
# Follow up:
#
#
# A straight forward solution using O(mn) space is probably a bad idea.
# A simple improvement uses O(m + n) space, but still not the best
# solution.
# Could you devise a constant space solution?
#
#
#
# Example 1:
#
# Input: matrix = [[1,1,1],[1,0,1],[1,1,1]]
# Output: [[1,0,1],[0,0,0],[1,0,1]]
#
#
# Example 2:
#
# Input: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
# Output: [[0,0,0,0],[0,4,5,0],[0,3,1,0]]
#
#
#
# Constraints:
#
#
# m == matrix.length
# n == matrix[0].length
# 1 <= m, n <= 200
# -10^9 <= matrix[i][j] <= 10^9from functools import reduce
# Time: O(m * n)
# Space: O(1)
class Solution(object):
# @param matrix, a list of lists of integers
# RETURN NOTHING, MODIFY matrix IN PLACE.
def setZeroes(self, matrix):
first_col = reduce(lambda acc, i: acc or matrix[i][0] == 0, xrange(len(matrix)), False)
first_row = reduce(lambda acc, j: acc or matrix[0][j] == 0, xrange(len(matrix[0])), False)
if first_col:
for i in xrange(len(matrix)):
matrix[i][0] = 0
if first_row:
104
for j in xrange(len(matrix[0])):
matrix[0][j] = 0
105
best-sightseeing-pair.py
# Given an array A of positive integers, A[i] represents the value of the i-th
# sightseeing spot, and two sightseeing spots i and j have distance j - i between
# them.
#
# The score of a pair (i < j) of sightseeing spots is (A[i] + A[j] + i - j) :
# the sum of the values of the sightseeing spots, minus the distance between them.
#
# Return the maximum score of a pair of sightseeing spots.
#
#
#
# Example 1:
#
# Input: [8,1,5,2,6]
# Output: 11
# Explanation: i = 0, j = 2, A[i] + A[j] + i - j = 8 + 5 + 0 - 2 = 11
#
#
#
#
# Note:
#
#
# 2 <= A.length <= 50000
# 1 <= A[i] <= 1000# Time: O(n)
# Space: O(1)
class Solution(object):
def maxScoreSightseeingPair(self, A):
"""
:type A: List[int]
:rtype: int
"""
result, curr = 0, 0
for x in A:
result = max(result, curr+x)
curr = max(curr, x)-1
return result
106
find-k-pairs-with-smallest-sums.py
# You are given two integer arrays nums1 and nums2 sorted in ascending order and
# an integer k.
#
# Define a pair (u,v) which consists of one element from the first array and one
# element from the second array.
#
# Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.
#
# Example 1:
#
# Input: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
# Output: [[1,2],[1,4],[1,6]]
# Explanation: The first 3 pairs are returned from the sequence:
# [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
#
# Example 2:
#
# Input: nums1 = [1,1,2], nums2 = [1,2,3], k = 2
# Output: [1,1],[1,1]
# Explanation: The first 2 pairs are returned from the sequence:
# [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]
#
# Example 3:
#
# Input: nums1 = [1,2], nums2 = [3], k = 3
# Output: [1,3],[2,3]
# Explanation: All possible pairs are returned from the sequence: [1,3],[2,3]# Time: O(k * log(min(n, m, k))),
# Space: O(min(n, m, k))
class Solution(object):
def kSmallestPairs(self, nums1, nums2, k):
"""
:type nums1: List[int]
:type nums2: List[int]
:type k: int
:rtype: List[List[int]]
"""
pairs = []
if len(nums1) > len(nums2):
tmp = self.kSmallestPairs(nums2, nums1, k)
for pair in tmp:
pairs.append([pair[1], pair[0]])
return pairs
min_heap = []
def push(i, j):
if i < len(nums1) and j < len(nums2):
heappush(min_heap, [nums1[i] + nums2[j], i, j])
push(0, 0)
while min_heap and len(pairs) < k:
_, i, j = heappop(min_heap)
pairs.append([nums1[i], nums2[j]])
push(i, j + 1)
if j == 0:
push(i + 1, 0) # at most queue min(n, m) space
107
return pairs
class Solution2(object):
def kSmallestPairs(self, nums1, nums2, k):
"""
:type nums1: List[int]
:type nums2: List[int]
:type k: int
:rtype: List[List[int]]
"""
return nsmallest(k, product(nums1, nums2), key=sum)
108
distribute-coins-in-binary-tree.py
# Given the root of a binary tree with N nodes, each node in the tree has
# node.val coins, and there are N coins total.
#
# In one move, we may choose two adjacent nodes and move one coin from one node
# to another. (The move may be from parent to child, or from child to parent.)
#
# Return the number of moves required to make every node have exactly one coin.
#
#
#
#
# Example 1:
#
#
#
# Input: [3,0,0]
# Output: 2
# Explanation: From the root of the tree, we move one coin to its left child,
# and one coin to its right child.
#
#
#
# Example 2:
#
#
#
# Input: [0,3,0]
# Output: 3
# Explanation: From the left child of the root, we move two coins to the root
# [taking two moves]. Then, we move one coin from the root of the tree to the
# right child.
#
#
#
# Example 3:
#
#
#
# Input: [1,0,2]
# Output: 2
#
#
#
# Example 4:
#
#
#
# Input: [1,0,0,null,3]
# Output: 4
#
#
#
#
# Note:
#
#
# 1<= N <= 100
# 0 <= node.val <= N# Time: O(n)
109
# Space: O(h)
class Solution(object):
def distributeCoins(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def dfs(root, result):
if not root:
return 0
left, right = dfs(root.left, result), dfs(root.right, result)
result[0] += abs(left) + abs(right)
return root.val + left + right - 1
result = [0]
dfs(root, result)
return result[0]
110
sort-characters-by-frequency.py
# Given a string, sort it in decreasing order based on the frequency of
# characters.
#
# Example 1:
# Input:
# "tree"
#
# Output:
# "eert"
#
# Explanation:
# 'e' appears twice while 'r' and 't' both appear once.
# So 'e' must appear before both 'r' and 't'. Therefore "eetr" is also a valid
# answer.
#
#
#
# Example 2:
# Input:
# "cccaaa"
#
# Output:
# "cccaaa"
#
# Explanation:
# Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer.
# Note that "cacaca" is incorrect, as the same characters must be together.
#
#
#
# Example 3:
# Input:
# "Aabb"
#
# Output:
# "bbAa"
#
# Explanation:
# "bbaA" is also a valid answer, but "Aabb" is incorrect.
# Note that 'A' and 'a' are treated as two different characters.# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def frequencySort(self, s):
"""
:type s: str
:rtype: str
"""
freq = collections.defaultdict(int)
for c in s:
freq[c] += 1
111
result = ""
for count in reversed(xrange(len(counts)-1)):
for c in counts[count]:
result += c * count
return result
112
minimum-area-rectangle.py
# Given a set of points in the xy-plane, determine the minimum area of a
# rectangle formed from these points, with sides parallel to the x and y axes.
#
# If there isn't any rectangle, return 0.
#
#
#
#
# Example 1:
#
# Input: [[1,1],[1,3],[3,1],[3,3],[2,2]]
# Output: 4
#
#
#
# Example 2:
#
# Input: [[1,1],[1,3],[3,1],[3,3],[4,1],[4,3]]
# Output: 2
#
#
#
#
# Note:
#
#
# 1 <= points.length <= 500
# 0 <= points[i][0] <= 40000
# 0 <= points[i][1] <= 40000
# All points are distinct.# Time: O(n^1.5) on average
# O(n^2) on worst
# Space: O(n)
import collections
class Solution(object):
def minAreaRect(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
nx = len(set(x for x, y in points))
ny = len(set(y for x, y in points))
p = collections.defaultdict(list)
if nx > ny:
for x, y in points:
p[x].append(y)
else:
for x, y in points:
p[y].append(x)
lookup = {}
result = float("inf")
for x in sorted(p):
p[x].sort()
for j in xrange(len(p[x])):
113
for i in xrange(j):
y1, y2 = p[x][i], p[x][j]
if (y1, y2) in lookup:
result = min(result, (x-lookup[y1, y2]) * abs(y2-y1))
lookup[y1, y2] = x
return result if result != float("inf") else 0
# Time: O(n^2)
# Space: O(n)
class Solution2(object):
def minAreaRect(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
lookup = set()
result = float("inf")
for x1, y1 in points:
for x2, y2 in lookup:
if (x1, y2) in lookup and (x2, y1) in lookup:
result = min(result, abs(x1-x2) * abs(y1-y2))
lookup.add((x1, y1))
return result if result != float("inf") else 0
114
sequential-digits.py
# An integer has sequential digits if and only if each digit in the number is
# one more than the previous digit.
#
# Return a sorted list of all the integers in the range [low, high] inclusive
# that have sequential digits.
#
#
# Example 1:
# Input: low = 100, high = 300
# Output: [123,234]
# Example 2:
# Input: low = 1000, high = 13000
# Output: [1234,2345,3456,4567,5678,6789,12345]
#
#
# Constraints:
#
#
# 10 <= low <= high <= 10^9# Time: O((8 + 1) * 8 / 2) = O(1)
# Space: O(8) = O(1)
import collections
class Solution(object):
def sequentialDigits(self, low, high):
"""
:type low: int
:type high: int
:rtype: List[int]
"""
result = []
q = collections.deque(range(1, 9))
while q:
num = q.popleft()
if num > high:
continue
if low <= num:
result.append(num)
if num%10+1 < 10:
q.append(num*10+num%10+1)
return result
115
perfect-squares.py
# Given a positive integer n, find the least number of perfect square numbers
# (for example, 1, 4, 9, 16, ...) which sum to n.
#
# Example 1:
#
# Input: n = 12
# Output: 3
# Explanation: 12 = 4 + 4 + 4.
#
# Example 2:
#
# Input: n = 13
# Output: 2
# Explanation: 13 = 4 + 9.# Time: O(n * sqrt(n))
# Space: O(n)
class Solution(object):
_num = [0]
def numSquares(self, n):
"""
:type n: int
:rtype: int
"""
num = self._num
while len(num) <= n:
num += min(num[-i*i] for i in xrange(1, int(len(num)**0.5+1))) + 1,
return num[n]
116
longest-turbulent-subarray.py
# Example 3:
#
# Input: [100]
# Output: 1# Time: O(n)
# Space: O(1)
class Solution(object):
def maxTurbulenceSize(self, A):
"""
:type A: List[int]
:rtype: int
"""
result = 1
start = 0
for i in xrange(1, len(A)):
if i == len(A)-1 or \
cmp(A[i-1], A[i]) * cmp(A[i], A[i+1]) != -1:
result = max(result, i-start+1)
start = i
return result
117
next-greater-node-in-linked-list.py
# Example 2:
#
# Input: [2,7,4,3,5]
# Output: [7,0,5,5,0]
#
#
#
# Example 3:
#
# Input: [1,7,5,1,9,2,5,1]
# Output: [7,9,9,9,0,5,0,0]
#
#
#
#
# Note:
#
#
# 1 <= node.val <= 10^9 for each node in the linked list.
# The given list has length in the range [0, 10000].# Time: O(n)
# Space: O(n)
class Solution(object):
def nextLargerNodes(self, head):
"""
:type head: ListNode
:rtype: List[int]
"""
result, stk = [], []
while head:
while stk and stk[-1][1] < head.val:
result[stk.pop()[0]] = head.val
stk.append([len(result), head.val])
result.append(0)
head = head.next
return result
118
friend-circles.py
# There are N students in a class. Some of them are friends, while some are not.
# Their friendship is transitive in nature. For example, if A is a direct friend
# of B, and B is a direct friend of C, then A is an indirect friend of C. And we
# defined a friend circle is a group of students who are direct or indirect
# friends.
#
# Given a N*N matrix M representing the friend relationship between students in
# the class. If M[i][j] = 1, then the ith and jth students are direct friends with
# each other, otherwise not. And you have to output the total number of friend
# circles among all the students.
#
# Example 1:
#
# Input:
# [[1,1,0],
# [1,1,0],
# [0,0,1]]
# Output: 2
# Explanation:The 0th and 1st students are direct friends, so they are in a
# friend circle.
# The 2nd student himself is in a friend circle. So return 2.
#
#
#
#
# Example 2:
#
# Input:
# [[1,1,0],
# [1,1,1],
# [0,1,1]]
# Output: 1
# Explanation:The 0th and 1st students are direct friends, the 1st and 2nd
# students are direct friends,
# so the 0th and 2nd students are indirect friends. All of them are in the same
# friend circle, so return 1.
#
#
#
#
# Constraints:
#
#
# 1 <= N <= 200
# M[i][i] == 1
# M[i][j] == M[j][i]# Time: O(n^2)
# Space: O(n)
class Solution(object):
def findCircleNum(self, M):
"""
:type M: List[List[int]]
:rtype: int
"""
class UnionFind(object):
def __init__(self, n):
self.set = range(n)
119
self.count = n
circles = UnionFind(len(M))
for i in xrange(len(M)):
for j in xrange(len(M)):
if M[i][j] and i != j:
circles.union_set(i, j)
return circles.count
120
score-of-parentheses.py
# Given a balanced parentheses string S, compute the score of the string based
# on the following rule:
#
#
# () has score 1
# AB has score A + B, where A and B are balanced parentheses strings.
# (A) has score 2 * A, where A is a balanced parentheses string.
#
#
#
#
#
# Example 1:
#
# Input: "()"
# Output: 1
#
#
#
# Example 2:
#
# Input: "(())"
# Output: 2
#
#
#
# Example 3:
#
# Input: "()()"
# Output: 2
#
#
#
# Example 4:
#
# Input: "(()(()))"
# Output: 6
#
#
#
#
# Note:
#
#
# S is a balanced parentheses string, containing only ( and ).
# 2 <= S.length <= 50# Time: O(n)
# Space: O(1)
class Solution(object):
def scoreOfParentheses(self, S):
"""
:type S: str
:rtype: int
"""
result, depth = 0, 0
for i in xrange(len(S)):
if S[i] == '(':
121
depth += 1
else:
depth -= 1
if S[i-1] == '(':
result += 2**depth
return result
# Time: O(n)
# Space: O(h)
class Solution2(object):
def scoreOfParentheses(self, S):
"""
:type S: str
:rtype: int
"""
stack = [0]
for c in S:
if c == '(':
stack.append(0)
else:
last = stack.pop()
stack[-1] += max(1, 2*last)
return stack[0]
122
beautiful-arrangement-ii.py
# Given two integers n and k, you need to construct a list which contains n
# different positive integers ranging from 1 to n and obeys the following
# requirement:
#
#
# Suppose this list is [a1, a2, a3, ... , an], then the list [|a1 - a2|, |a2 -
# a3|, |a3 - a4|, ... , |an-1 - an|] has exactly k distinct integers.
#
#
#
# If there are multiple answers, print any of them.
#
#
# Example 1:
#
# Input: n = 3, k = 1
# Output: [1, 2, 3]
# Explanation: The [1, 2, 3] has three different positive integers ranging from
# 1 to 3, and the [1, 1] has exactly 1 distinct integer: 1.
#
#
#
# Example 2:
#
# Input: n = 3, k = 2
# Output: [1, 3, 2]
# Explanation: The [1, 3, 2] has three different positive integers ranging from
# 1 to 3, and the [2, 1] has exactly 2 distinct integers: 1 and 2.
#
#
#
# Note:
#
#
# The n and k are in the range 1 <= k < n <= 104.# Time: O(n)
# Space: O(1)
class Solution(object):
def constructArray(self, n, k):
"""
:type n: int
:type k: int
:rtype: List[int]
"""
result = []
left, right = 1, n
while left <= right:
if k % 2:
result.append(left)
left += 1
else:
result.append(right)
right -= 1
if k > 1:
k -= 1
return result
123
matrix-block-sum.py
# Given a m * n matrix mat and an integer K, return a matrix answer where each
# answer[i][j] is the sum of all elements mat[r][c] for i - K <= r <= i + K, j - K
# <= c <= j + K, and (r, c) is a valid position in the matrix.
#
# Example 1:
#
# Input: mat = [[1,2,3],[4,5,6],[7,8,9]], K = 1
# Output: [[12,21,16],[27,45,33],[24,39,28]]
#
#
# Example 2:
#
# Input: mat = [[1,2,3],[4,5,6],[7,8,9]], K = 2
# Output: [[45,45,45],[45,45,45],[45,45,45]]
#
#
#
# Constraints:
#
#
# m == mat.length
# n == mat[i].length
# 1 <= m, n, K <= 100
# 1 <= mat[i][j] <= 100# Time: O(m * n)
# Space: O(m * n)
class Solution(object):
def matrixBlockSum(self, mat, K):
"""
:type mat: List[List[int]]
:type K: int
:rtype: List[List[int]]
"""
m, n = len(mat), len(mat[0])
accu = [[0 for _ in xrange(n+1)] for _ in xrange(m+1)]
for i in xrange(m):
for j in xrange(n):
accu[i+1][j+1] = accu[i+1][j]+accu[i][j+1]-accu[i][j]+mat[i][j]
result = [[0 for _ in xrange(n)] for _ in xrange(m)]
for i in xrange(m):
for j in xrange(n):
r1, c1, r2, c2 = max(i-K, 0), max(j-K, 0), min(i+K+1, m), min(j+K+1, n)
result[i][j] = accu[r2][c2]-accu[r1][c2]-accu[r2][c1]+accu[r1][c1]
return result
124
maximum-of-absolute-value-expression.py
# Given two arrays of integers with equal lengths, return the maximum value of:
#
# |arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j|
#
# where the maximum is taken over all 0 <= i, j < arr1.length.
#
#
# Example 1:
#
# Input: arr1 = [1,2,3,4], arr2 = [-1,4,5,6]
# Output: 13
#
#
# Example 2:
#
# Input: arr1 = [1,-2,-5,0,10], arr2 = [0,-2,-1,-7,-4]
# Output: 20
#
#
#
# Constraints:
#
#
# 2 <= arr1.length == arr2.length <= 40000
# -10^6 <= arr1[i], arr2[i] <= 10^6# Time: O(n)
# Space: O(1)
class Solution(object):
def maxAbsValExpr(self, arr1, arr2):
"""
:type arr1: List[int]
:type arr2: List[int]
:rtype: int
"""
# 1. max(|arr1[i]-arr1[j]| + |arr2[i]-arr2[j]| + |i-j| for i > j)
# = max(|arr1[i]-arr1[j]| + |arr2[i]-arr2[j]| + |i-j| for j > i)
# 2. for i > j:
# (|arr1[i]-arr1[j]| + |arr2[i]-arr2[j]| + |i-j|)
# >= c1*(arr1[i]-arr1[j]) + c2*(arr2[i]-arr2[j]) + i-j for c1 in (1, -1), c2 in (1, -1)
# = (c1*arr1[i]+c2*arr2[i]+i) - (c1*arr1[j]+c2*arr2[j]+j) for c1 in (1, -1), c2 in (1, -1)
# 1 + 2 => max(|arr1[i]-arr1[j]| + |arr2[i]-arr2[j]| + |i-j| for i != j)
# = max((c1*arr1[i]+c2*arr2[i]+i) - (c1*arr1[j]+c2*arr2[j]+j)
# for c1 in (1, -1), c2 in (1, -1) for i > j)
result = 0
for c1 in [1, -1]:
for c2 in [1, -1]:
min_prev = float("inf")
for i in xrange(len(arr1)):
curr = c1*arr1[i] + c2*arr2[i] + i
result = max(result, curr-min_prev)
min_prev = min(min_prev, curr)
return result
# Time: O(n)
# Space: O(1)
class Solution2(object):
def maxAbsValExpr(self, arr1, arr2):
125
"""
:type arr1: List[int]
:type arr2: List[int]
:rtype: int
"""
return max(max(c1*arr1[i] + c2*arr2[i] + i for i in xrange(len(arr1))) -
min(c1*arr1[i] + c2*arr2[i] + i for i in xrange(len(arr1)))
for c1 in [1, -1] for c2 in [1, -1])
126
single-element-in-a-sorted-array.py
# You are given a sorted array consisting of only integers where every element
# appears exactly twice, except for one element which appears exactly once. Find
# this single element that appears only once.
#
# Follow up: Your solution should run in O(log n) time and O(1) space.
#
#
# Example 1:
# Input: nums = [1,1,2,3,3,4,4,8,8]
# Output: 2
# Example 2:
# Input: nums = [3,3,7,7,10,11,11]
# Output: 10
#
#
# Constraints:
#
#
# 1 <= nums.length <= 10^5
# 0 <= nums[i] <= 10^5# Time: O(logn)
# Space: O(1)
class Solution(object):
def singleNonDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left, right = 0, len(nums)-1
while left <= right:
mid = left + (right - left) / 2
if not (mid%2 == 0 and mid+1 < len(nums) and \
nums[mid] == nums[mid+1]) and \
not (mid%2 == 1 and nums[mid] == nums[mid-1]):
right = mid-1
else:
left = mid+1
return nums[left]
lo, hi = 0, len(nums) - 1
while lo < hi:
mid = (lo + hi) / 2
if nums[mid] == nums[mid ^ 1]:
lo = mid + 1
else:
hi = mid
return nums[lo]
127
group-anagrams.py
# Given an array of strings strs, group the anagrams together. You can return
# the answer in any order.
#
# An Anagram is a word or phrase formed by rearranging the letters of a
# different word or phrase, typically using all the original letters exactly once.
#
#
# Example 1:
# Input: strs = ["eat","tea","tan","ate","nat","bat"]
# Output: [["bat"],["nat","tan"],["ate","eat","tea"]]
# Example 2:
# Input: strs = [""]
# Output: [[""]]
# Example 3:
# Input: strs = ["a"]
# Output: [["a"]]
#
#
# Constraints:
#
#
# 1 <= strs.length <= 104
# 0 <= strs[i].length <= 100
# strs[i] consists of lower-case English letters.# Time: O(n * glogg), g is the max size of groups.
# Space: O(n)
import collections
class Solution(object):
def groupAnagrams(self, strs):
"""
:type strs: List[str]
:rtype: List[List[str]]
"""
anagrams_map, result = collections.defaultdict(list), []
for s in strs:
sorted_str = ("").join(sorted(s))
anagrams_map[sorted_str].append(s)
for anagram in anagrams_map.values():
anagram.sort()
result.append(anagram)
return result
128
uncrossed-lines.py
# We write the integers of A and B (in the order they are given) on two separate
# horizontal lines.
#
# Now, we may draw connecting lines: a straight line connecting two numbers A[i]
# and B[j] such that:
#
#
# A[i] == B[j];
# The line we draw does not intersect any other connecting (non-
# horizontal) line.
#
#
# Note that a connecting lines cannot intersect even at the endpoints: each
# number can only belong to one connecting line.
#
# Return the maximum number of connecting lines we can draw in this way.
#
#
#
# Example 1:
#
# Input: A = [1,4,2], B = [1,2,4]
# Output: 2
# Explanation: We can draw 2 uncrossed lines as in the diagram.
# We cannot draw 3 uncrossed lines, because the line from A[1]=4 to B[2]=4 will
# intersect the line from A[2]=2 to B[1]=2.
#
#
#
# Example 2:
#
# Input: A = [2,5,1,2,5], B = [10,5,2,1,5,2]
# Output: 3
#
#
#
# Example 3:
#
# Input: A = [1,3,7,1,7,5], B = [1,9,2,5,1]
# Output: 2
#
#
#
#
#
# Note:
#
#
# 1 <= A.length <= 500
# 1 <= B.length <= 500
# 1 <= A[i], B[i] <= 2000# Time: O(m * n)
# Space: O(min(m, n))
class Solution(object):
def maxUncrossedLines(self, A, B):
"""
:type A: List[int]
:type B: List[int]
129
:rtype: int
"""
if len(A) < len(B):
return self.maxUncrossedLines(B, A)
130
partition-list.py
# Given a linked list and a value x, partition it such that all nodes less than
# x come before nodes greater than or equal to x.
#
# You should preserve the original relative order of the nodes in each of the
# two partitions.
#
# Example:
#
# Input: head = 1->4->3->2->5->2, x = 3
# Output: 1->2->2->4->3->5# Time: O(n)
# Space: O(1)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{} -> {}".format(self.val, repr(self.next))
class Solution(object):
# @param head, a ListNode
# @param x, an integer
# @return a ListNode
def partition(self, head, x):
dummySmaller, dummyGreater = ListNode(-1), ListNode(-1)
smaller, greater = dummySmaller, dummyGreater
while head:
if head.val < x:
smaller.next = head
smaller = smaller.next
else:
greater.next = head
greater = greater.next
head = head.next
smaller.next = dummyGreater.next
greater.next = None
return dummySmaller.next
131
filling-bookcase-shelves.py
# We have a sequence of books: the i-th book has thickness books[i][0] and
# height books[i][1].
#
# We want to place these books in order onto bookcase shelves that have total
# width shelf_width.
#
# We choose some of the books to place on this shelf (such that the sum of their
# thickness is <= shelf_width), then build another level of shelf of the bookcase
# so that the total height of the bookcase has increased by the maximum height of
# the books we just put down. We repeat this process until there are no more
# books to place.
#
# Note again that at each step of the above process, the order of the books we
# place is the same order as the given sequence of books. For example, if we have
# an ordered list of 5 books, we might place the first and second book onto the
# first shelf, the third book on the second shelf, and the fourth and fifth book
# on the last shelf.
#
# Return the minimum possible height that the total bookshelf can be after
# placing shelves in this manner.
#
#
# Example 1:
#
# Input: books = [[1,1],[2,3],[2,3],[1,1],[1,1],[1,1],[1,2]], shelf_width = 4
# Output: 6
# Explanation:
# The sum of the heights of the 3 shelves are 1 + 3 + 2 = 6.
# Notice that book number 2 does not have to be on the first shelf.
#
#
#
# Constraints:
#
#
# 1 <= books.length <= 1000
# 1 <= books[i][0] <= shelf_width <= 1000
# 1 <= books[i][1] <= 1000# Time: O(n^2)
# Space: O(n)
class Solution(object):
def minHeightShelves(self, books, shelf_width):
"""
:type books: List[List[int]]
:type shelf_width: int
:rtype: int
"""
dp = [float("inf") for _ in xrange(len(books)+1)]
dp[0] = 0
for i in xrange(1, len(books)+1):
max_width = shelf_width
max_height = 0
for j in reversed(xrange(i)):
if max_width-books[j][0] < 0:
break
max_width -= books[j][0]
max_height = max(max_height, books[j][1])
dp[i] = min(dp[i], dp[j]+max_height)
132
return dp[len(books)]
133
sum-of-mutated-array-closest-to-target.py
# Given an integer array arr and a target value target, return the
# integer value such that when we change all the integers larger than value in the
# given array to be equal to value, the sum of the array gets as close as possible
# (in absolute difference) to target.
#
# In case of a tie, return the minimum such integer.
#
# Notice that the answer is not neccesarilly a number from arr.
#
#
# Example 1:
#
# Input: arr = [4,9,3], target = 10
# Output: 3
# Explanation: When using 3 arr converts to [3, 3, 3] which sums 9 and that's
# the optimal answer.
#
#
# Example 2:
#
# Input: arr = [2,3,5], target = 10
# Output: 5
#
#
# Example 3:
#
# Input: arr = [60864,25176,27249,21296,20204], target = 56803
# Output: 11361
#
#
#
# Constraints:
#
#
# 1 <= arr.length <= 10^4
# 1 <= arr[i], target <= 10^5# Time: O(nlogn)
# Space: O(1)
class Solution(object):
def findBestValue(self, arr, target):
"""
:type arr: List[int]
:type target: int
:rtype: int
"""
arr.sort(reverse=True)
max_arr = arr[0]
while arr and arr[-1]*len(arr) <= target:
target -= arr.pop()
# let x = ceil(t/n)-1
# (1) (t/n-1/2) <= x:
# return x, which is equal to ceil(t/n)-1 = ceil(t/n-1/2) = (2t+n-1)//2n
# (2) (t/n-1/2) > x:
# return x+1, which is equal to ceil(t/n) = ceil(t/n-1/2) = (2t+n-1)//2n
# (1) + (2) => both return (2t+n-1)//2n
return max_arr if not arr else (2*target+len(arr)-1)//(2*len(arr))
134
# Time: O(nlogn)
# Space: O(1)
class Solution2(object):
def findBestValue(self, arr, target):
"""
:type arr: List[int]
:type target: int
:rtype: int
"""
arr.sort(reverse=True)
max_arr = arr[0]
while arr and arr[-1]*len(arr) <= target:
target -= arr.pop()
if not arr:
return max_arr
x = (target-1)//len(arr)
return x if target-x*len(arr) <= (x+1)*len(arr)-target else x+1
135
2-keys-keyboard.py
# Initially on a notepad only one character 'A' is present. You can perform two
# operations on this notepad for each step:
#
#
# Copy All: You can copy all the characters present on the notepad
# (partial copy is not allowed).
# Paste: You can paste the characters which are copied last time.
#
#
#
#
# Given a number n. You have to get exactly n 'A' on the notepad by performing
# the minimum number of steps permitted. Output the minimum number of steps to get
# n 'A'.
#
# Example 1:
#
# Input: 3
# Output: 3
# Explanation:
# Intitally, we have one character 'A'.
# In step 1, we use Copy All operation.
# In step 2, we use Paste operation to get 'AA'.
# In step 3, we use Paste operation to get 'AAA'.
#
#
#
#
# Note:
#
#
# The n will be in the range [1, 1000].# Time: O(sqrt(n))
# Space: O(1)
class Solution(object):
def minSteps(self, n):
"""
:type n: int
:rtype: int
"""
result = 0
p = 2
# the answer is the sum of prime factors
while p**2 <= n:
while n % p == 0:
result += p
n //= p
p += 1
if n > 1:
result += n
return result
136
binary-search-tree-iterator.py
# Implement an iterator over a binary search tree (BST). Your iterator will be
# initialized with the root node of a BST.
#
# Calling next() will return the next smallest number in the BST.
#
#
#
#
#
#
# Example:
#
#
#
# BSTIterator iterator = new BSTIterator(root);
# iterator.next(); // return 3
# iterator.next(); // return 7
# iterator.hasNext(); // return true
# iterator.next(); // return 9
# iterator.hasNext(); // return true
# iterator.next(); // return 15
# iterator.hasNext(); // return true
# iterator.next(); // return 20
# iterator.hasNext(); // return false
#
#
#
#
# Note:
#
#
# next() and hasNext() should run in average O(1) time and uses O(h)
# memory, where h is the height of the tree.
# You may assume that next() call will always be valid, that is, there
# will be at least a next smallest number in the BST when next() is called.# Time: O(1)
# Space: O(h), h is height of binary tree
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class BSTIterator(object):
# @param root, a binary search tree's root node
def __init__(self, root):
self.stack = []
self.cur = root
137
self.cur = self.cur.left
self.cur = self.stack.pop()
node = self.cur
self.cur = self.cur.right
return node.val
138
find-the-duplicate-number.py
# Given an array nums containing n + 1 integers where each integer is between 1
# and n (inclusive), prove that at least one duplicate number must exist. Assume
# that there is only one duplicate number, find the duplicate one.
#
# Example 1:
#
# Input: [1,3,4,2,2]
# Output: 2
#
#
# Example 2:
#
# Input: [3,1,3,4,2]
# Output: 3
#
# Note:
#
#
# You must not modify the array (assume the array is read only).
# You must use only constant, O(1) extra space.
# Your runtime complexity should be less than O(n2).
# There is only one duplicate number in the array, but it could be
# repeated more than once.# Time: O(n)
# Space: O(1)
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# Treat each (key, value) pair of the array as the (pointer, next) node of the linked list,
# thus the duplicated number will be the begin of the cycle in the linked list.
# Besides, there is always a cycle in the linked list which
# starts from the first element of the array.
slow = nums[0]
fast = nums[nums[0]]
while slow != fast:
slow = nums[slow]
fast = nums[nums[fast]]
fast = 0
while slow != fast:
slow = nums[slow]
fast = nums[fast]
return slow
# Time: O(nlogn)
# Space: O(1)
# Binary search method.
class Solution2(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left, right = 1, len(nums) - 1
139
while left <= right:
mid = left + (right - left) / 2
# Get count of num <= mid.
count = 0
for num in nums:
if num <= mid:
count += 1
if count > mid:
right = mid - 1
else:
left = mid + 1
return left
# Time: O(n)
# Space: O(n)
class Solution3(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
duplicate = 0
# Mark the value as visited by negative.
for num in nums:
if nums[abs(num) - 1] > 0:
nums[abs(num) - 1] *= -1
else:
duplicate = abs(num)
break
# Rollback the value.
for num in nums:
if nums[abs(num) - 1] < 0:
nums[abs(num) - 1] *= -1
else:
break
return duplicate
140
merge-intervals.py
# Given a collection of intervals, merge all overlapping intervals.
#
# Example 1:
#
# Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
# Output: [[1,6],[8,10],[15,18]]
# Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
#
#
# Example 2:
#
# Input: intervals = [[1,4],[4,5]]
# Output: [[1,5]]
# Explanation: Intervals [1,4] and [4,5] are considered overlapping.
#
# NOTE: input types have been changed on April 15, 2019. Please reset to default
# code definition to get new method signature.
#
#
# Constraints:
#
#
# intervals[i][0] <= intervals[i][1]# Time: O(nlogn)
# Space: O(1)
class Interval(object):
def __init__(self, s=0, e=0):
self.start = s
self.end = e
def __repr__(self):
return "[{}, {}]".format(self.start, self.end)
class Solution(object):
def merge(self, intervals):
"""
:type intervals: List[Interval]
:rtype: List[Interval]
"""
if not intervals:
return intervals
intervals.sort(key=lambda x: x.start)
iterator = iter(intervals)
result = [next(iterator)]
for current in iterator:
prev = result[-1]
if current.start <= prev.end:
prev.end = max(current.end, prev.end)
else:
result.append(current)
return result
141
largest-values-from-labels.py
# Example 1:
#
# Input: values = [5,4,3,2,1], labels = [1,1,2,2,3], num_wanted = 3, use_limit =
# 1
# Output: 9
# Explanation: The subset chosen is the first, third, and fifth item.
#
#
#
# Example 2:
#
# Input: values = [5,4,3,2,1], labels = [1,3,3,3,2], num_wanted = 3, use_limit =
# 2
# Output: 12
# Explanation: The subset chosen is the first, second, and third item.
#
#
#
# Example 3:
#
# Input: values = [9,8,8,7,6], labels = [0,0,0,1,1], num_wanted = 3, use_limit =
# 1
# Output: 16
# Explanation: The subset chosen is the first and fourth item.
#
#
#
# Example 4:
#
# Input: values = [9,8,8,7,6], labels = [0,0,0,1,1], num_wanted = 3, use_limit =
# 2
# Output: 24
# Explanation: The subset chosen is the first, second, and fourth item.
#
#
#
#
# Note:
#
#
# 1 <= values.length == labels.length <= 20000
# 0 <= values[i], labels[i] <= 20000
# 1 <= num_wanted, use_limit <= values.length# Time: O(nlogn)
# Space: O(n)
import collections
class Solution(object):
def largestValsFromLabels(self, values, labels, num_wanted, use_limit):
"""
:type values: List[int]
:type labels: List[int]
:type num_wanted: int
:type use_limit: int
:rtype: int
"""
counts = collections.defaultdict(int)
142
val_labs = zip(values,labels)
val_labs.sort(reverse=True)
result = 0
for val, lab in val_labs:
if counts[lab] >= use_limit:
continue
result += val
counts[lab] += 1
num_wanted -= 1
if num_wanted == 0:
break
return result
143
3sum-closest.py
# Given an array nums of n integers and an integer target, find three integers
# in nums such that the sum is closest to target. Return the sum of the three
# integers. You may assume that each input would have exactly one solution.
#
#
# Example 1:
#
# Input: nums = [-1,2,1,-4], target = 1
# Output: 2
# Explanation: The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
#
#
#
# Constraints:
#
#
# 3 <= nums.length <= 10^3
# -10^3 <= nums[i] <= 10^3
# -10^4 <= target <= 10^4# Time: O(n^2)
# Space: O(1)
class Solution(object):
def threeSumClosest(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
nums, result, min_diff, i = sorted(nums), float("inf"), float("inf"), 0
while i < len(nums) - 2:
if i == 0 or nums[i] != nums[i - 1]:
j, k = i + 1, len(nums) - 1
while j < k:
diff = nums[i] + nums[j] + nums[k] - target
if abs(diff) < min_diff:
min_diff = abs(diff)
result = nums[i] + nums[j] + nums[k]
if diff < 0:
j += 1
elif diff > 0:
k -= 1
else:
return target
i += 1
return result
144
solve-the-equation.py
# Solve a given equation and return the value of x in the form of string
# "x=#value". The equation contains only '+', '-' operation, the variable x and
# its coefficient.
#
#
#
# If there is no solution for the equation, return "No solution".
#
#
# If there are infinite solutions for the equation, return "Infinite solutions".
#
#
# If there is exactly one solution for the equation, we ensure that the value of
# x is an integer.
#
#
# Example 1:
#
# Input: "x+5-3+x=6+x-2"
# Output: "x=2"
#
#
#
# Example 2:
#
# Input: "x=x"
# Output: "Infinite solutions"
#
#
#
# Example 3:
#
# Input: "2x=x"
# Output: "x=0"
#
#
#
# Example 4:
#
# Input: "2x+3x-6x=x+2"
# Output: "x=-1"
#
#
#
# Example 5:
#
# Input: "x=x+2"
# Output: "No solution"# Time: O(n)
# Space: O(n)
import re
class Solution(object):
def solveEquation(self, equation):
"""
:type equation: str
:rtype: str
145
"""
a, b, side = 0, 0, 1
for eq, sign, num, isx in re.findall('(=)|([-+]?)(\d*)(x?)', equation):
if eq:
side = -1
elif isx:
a += side * int(sign + '1') * int(num or 1)
elif num:
b -= side * int(sign + num)
return 'x=%d' % (b / a) if a else 'No solution' if b else 'Infinite solutions'
146
minimum-height-trees.py
# For an undirected graph with tree characteristics, we can choose any node as
# the root. The result graph is then a rooted tree. Among all possible rooted
# trees, those with minimum height are called minimum height trees (MHTs). Given
# such a graph, write a function to find all the MHTs and return a list of their
# root labels.
#
# Format
#
# The graph contains n nodes which are labeled from 0 to n - 1. You will be
# given the number n and a list of undirected edges (each edge is a pair of
# labels).
#
# You can assume that no duplicate edges will appear in edges. Since all edges
# are undirected, [0, 1] is the same as [1, 0] and thus will not appear together
# in edges.
#
# Example 1 :
#
# Input: n = 4, edges = [[1, 0], [1, 2], [1, 3]]
#
# 0
# |
# 1
# / \
# 2 3
#
# Output: [1]
#
#
# Example 2 :
#
# Input: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
#
# 0 1 2
# \ | /
# 3
# |
# 4
# |
# 5
#
# Output: [3, 4]
#
# Note:
#
#
# According to the definition of tree on Wikipedia: “a tree is an
# undirected graph in which any two vertices are connected by exactly one path. In
# other words, any connected graph without simple cycles is a tree.”
# The height of a rooted tree is the number of edges on the longest
# downward path between the root and a leaf.# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def findMinHeightTrees(self, n, edges):
147
"""
:type n: int
:type edges: List[List[int]]
:rtype: List[int]
"""
if n == 1:
return [0]
neighbors = collections.defaultdict(set)
for u, v in edges:
neighbors[u].add(v)
neighbors[v].add(u)
return list(unvisited)
148
continuous-subarray-sum.py
# Given a list of non-negative numbers and a target integer k, write a function
# to check if the array has a continuous subarray of size at least 2 that sums up
# to a multiple of k, that is, sums up to n*k where n is also an integer.
#
#
#
# Example 1:
#
# Input: [23, 2, 4, 6, 7], k=6
# Output: True
# Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to
# 6.
#
#
# Example 2:
#
# Input: [23, 2, 6, 4, 7], k=6
# Output: True
# Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and
# sums up to 42.
#
#
#
# Constraints:
#
#
# The length of the array won't exceed 10,000.
# You may assume the sum of all the numbers is in the range of a signed
# 32-bit integer.# Time: O(n)
# Space: O(k)
class Solution(object):
def checkSubarraySum(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
count = 0
lookup = {0: -1}
for i, num in enumerate(nums):
count += num
if k:
count %= k
if count in lookup:
if i - lookup[count] > 1:
return True
else:
lookup[count] = i
return False
149
brick-wall.py
# There is a brick wall in front of you. The wall is rectangular and has several
# rows of bricks. The bricks have the same height but different width. You want to
# draw a vertical line from the top to the bottom and cross the least bricks.
#
# The brick wall is represented by a list of rows. Each row is a list of
# integers representing the width of each brick in this row from left to right.
#
# If your line go through the edge of a brick, then the brick is not considered
# as crossed. You need to find out how to draw the line to cross the least bricks
# and return the number of crossed bricks.
#
# You cannot draw a line just along one of the two vertical edges of the wall,
# in which case the line will obviously cross no bricks.
#
#
#
# Example:
#
# Input: [[1,2,2,1],
# [3,1,2],
# [1,3,2],
# [2,4],
# [3,1,2],
# [1,3,1,1]]
#
# Output: 2
#
# Explanation:
#
#
#
#
#
# Note:
#
#
# The width sum of bricks in different rows are the same and won't exceed
# INT_MAX.
# The number of bricks in each row is in range [1,10,000]. The height of
# wall is in range [1,10,000]. Total number of bricks of the wall won't exceed
# 20,000.# Time: O(n), n is the total number of the bricks
# Space: O(m), m is the total number different widths
import collections
class Solution(object):
def leastBricks(self, wall):
"""
:type wall: List[List[int]]
:rtype: int
"""
widths = collections.defaultdict(int)
result = len(wall)
for row in wall:
width = 0
for i in xrange(len(row)-1):
width += row[i]
150
widths[width] += 1
result = min(result, len(wall) - widths[width])
return result
151
gray-code.py
# The gray code is a binary numeral system where two successive values differ in
# only one bit.
#
# Given a non-negative integer n representing the total number of bits in the
# code, print the sequence of gray code. A gray code sequence must begin with 0.
#
# Example 1:
#
# Input: 2
# Output: [0,1,3,2]
# Explanation:
# 00 - 0
# 01 - 1
# 11 - 3
# 10 - 2
#
# For a given n, a gray code sequence may not be uniquely defined.
# For example, [0,2,3,1] is also a valid gray code sequence.
#
# 00 - 0
# 10 - 2
# 11 - 3
# 01 - 1
#
#
# Example 2:
#
# Input: 0
# Output: [0]
# Explanation: We define the gray code sequence to begin with 0.
# A gray code sequence of n has size = 2n, which for n = 0 the size
# is 20 = 1.
# Therefore, for n = 0 the gray code sequence is [0].# Time: O(2^n)
# Space: O(1)
class Solution(object):
def grayCode(self, n):
"""
:type n: int
:rtype: List[int]
"""
result = [0]
for i in xrange(n):
for n in reversed(result):
result.append(1 << i | n)
return result
152
odd-even-linked-list.py
# Given a singly linked list, group all odd nodes together followed by the even
# nodes. Please note here we are talking about the node number and not the value
# in the nodes.
#
# You should try to do it in place. The program should run in O(1) space
# complexity and O(nodes) time complexity.
#
# Example 1:
#
# Input: 1->2->3->4->5->NULL
# Output: 1->3->5->2->4->NULL
#
#
# Example 2:
#
# Input: 2->1->3->5->6->4->7->NULL
# Output: 2->3->6->7->1->5->4->NULL
#
#
#
# Constraints:
#
#
# The relative order inside both the even and odd groups should remain as
# it was in the input.
# The first node is considered odd, the second node even and so on ...
# The length of the linked list is between [0, 10^4].# Time: O(n)
# Space: O(1)
class Solution(object):
def oddEvenList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head:
odd_tail, cur = head, head.next
while cur and cur.next:
even_head = odd_tail.next
odd_tail.next = cur.next
odd_tail = odd_tail.next
cur.next = odd_tail.next
odd_tail.next = even_head
cur = cur.next
return head
153
# longest-uncommon-subsequence-ii.py
```python
# Given a list of strings, you need to find the longest uncommon subsequence
# among them. The longest uncommon subsequence is defined as the longest
# subsequence of one of these strings and this subsequence should not be any
# subsequence of the other strings.
#
#
#
# A subsequence is a sequence that can be derived from one sequence by deleting
# some characters without changing the order of the remaining elements. Trivially,
# any string is a subsequence of itself and an empty string is a subsequence of
# any string.
#
#
#
# The input will be a list of strings, and the output needs to be the length of
# the longest uncommon subsequence. If the longest uncommon subsequence doesn't
# exist, return -1.
#
#
# Example 1:
#
# Input: "aba", "cdc", "eae"
# Output: 3
#
#
#
# Note:
#
# All the given strings' lengths will not exceed 10.
# The length of the given list will be in the range of [2, 50].# Time: O(l * n^2)
# Space: O(1)
class Solution(object):
def findLUSlength(self, A):
def subseq(w1, w2):
# True iff word1 is a subsequence of word2.
i = 0
for c in w2:
if i < len(w1) and w1[i] == c:
i += 1
return i == len(w1)
A.sort(key=len, reverse=True)
for i, word1 in enumerate(A):
if all(not subseq(word1, word2)
for j, word2 in enumerate(A) if i != j):
return len(word1)
return -1```
newpage
# vertical-order-traversal-of-a-binary-tree.py
```python
# Example 2:
#
#
#
# Input: [1,2,3,4,5,6,7]
154
# Output: [[4],[2],[1,5,6],[3],[7]]
# Explanation:
# The node with value 5 and the node with value 6 have the same position
# according to the given scheme.
# However, in the report "[1,5,6]", the node value of 5 comes first since 5 is
# smaller than 6.# Time: O(nlogn)
# Space: O(n)
import collections
class Solution(object):
def verticalTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
def dfs(node, lookup, x, y):
if not node:
return
lookup[x][y].append(node)
dfs(node.left, lookup, x-1, y+1)
dfs(node.right, lookup, x+1, y+1)
result = []
for x in sorted(lookup):
report = []
for y in sorted(lookup[x]):
report.extend(sorted(node.val for node in lookup[x][y]))
result.append(report)
return result
155
basic-calculator-ii.py
# Implement a basic calculator to evaluate a simple expression string.
#
# The expression string contains only non-negative integers, +, -, *, /
# operators and empty spaces . The integer division should truncate toward zero.
#
# Example 1:
#
# Input: "3+2*2"
# Output: 7
#
#
# Example 2:
#
# Input: " 3/2 "
# Output: 1
#
# Example 3:
#
# Input: " 3+5 / 2 "
# Output: 5
#
#
# Note:
#
#
# You may assume that the given expression is always valid.
# Do not use the eval built-in library function.# Time: O(n)
# Space: O(n)
class Solution(object):
# @param {string} s
# @return {integer}
def calculate(self, s):
operands, operators = [], []
operand = ""
for i in reversed(xrange(len(s))):
if s[i].isdigit():
operand += s[i]
if i == 0 or not s[i-1].isdigit():
operands.append(int(operand[::-1]))
operand = ""
elif s[i] == ')' or s[i] == '*' or s[i] == '/':
operators.append(s[i])
elif s[i] == '+' or s[i] == '-':
while operators and \
(operators[-1] == '*' or operators[-1] == '/'):
self.compute(operands, operators)
operators.append(s[i])
elif s[i] == '(':
while operators[-1] != ')':
self.compute(operands, operators)
operators.pop()
while operators:
self.compute(operands, operators)
return operands[-1]
156
def compute(self, operands, operators):
left, right = operands.pop(), operands.pop()
op = operators.pop()
if op == '+':
operands.append(left + right)
elif op == '-':
operands.append(left - right)
elif op == '*':
operands.append(left * right)
elif op == '/':
operands.append(left / right)
157
populating-next-right-pointers-in-each-node-ii.py
# Given a binary tree
#
# struct Node {
# int val;
# Node *left;
# Node *right;
# Node *next;
# }
#
#
# Populate each next pointer to point to its next right node. If there is no
# next right node, the next pointer should be set to NULL.
#
# Initially, all next pointers are set to NULL.
#
#
#
# Follow up:
#
#
# You may only use constant extra space.
# Recursive approach is fine, you may assume implicit stack space does not
# count as extra space for this problem.
#
#
#
# Example 1:
#
#
#
# Input: root = [1,2,3,4,5,null,7]
# Output: [1,#,2,3,#,4,5,7,#]
# Explanation: Given the above binary tree (Figure A), your function should
# populate each next pointer to point to its next right node, just like in Figure
# B. The serialized output is in level order as connected by the next pointers,
# with '#' signifying the end of each level.
#
#
#
# Constraints:
#
#
# The number of nodes in the given tree is less than 6000.
# -100 <= node.val <= 100# Time: O(n)
# Space: O(1)
class Solution(object):
# @param root, a tree node
# @return nothing
158
def connect(self, root):
head = root
pre = Node(0)
cur = pre
while root:
while root:
if root.left:
cur.next = root.left
cur = cur.next
if root.right:
cur.next = root.right
cur = cur.next
root = root.next
root, cur = pre.next, pre
cur.next = None
return head
159
all-elements-in-two-binary-search-trees.py
# Given two binary search trees root1 and root2.
#
# Return a list containing all the integers from both trees sorted in ascending
# order.
#
#
# Example 1:
#
# Input: root1 = [2,1,4], root2 = [1,0,3]
# Output: [0,1,1,2,3,4]
#
#
# Example 2:
#
# Input: root1 = [0,-10,10], root2 = [5,1,7,0,2]
# Output: [-10,0,0,1,2,5,7,10]
#
#
# Example 3:
#
# Input: root1 = [], root2 = [5,1,7,0,2]
# Output: [0,1,2,5,7]
#
#
# Example 4:
#
# Input: root1 = [0,-10,10], root2 = []
# Output: [-10,0,10]
#
#
# Example 5:
#
# Input: root1 = [1,null,8], root2 = [8,1]
# Output: [1,1,8,8]
#
#
#
# Constraints:
#
#
# Each tree has at most 5000 nodes.
# Each node's value is between [-10^5, 10^5].# Time: O(n)
# Space: O(h)
class Solution(object):
def getAllElements(self, root1, root2):
"""
:type root1: TreeNode
:type root2: TreeNode
:rtype: List[int]
160
"""
def inorder_gen(root):
result, stack = [], [(root, False)]
while stack:
root, is_visited = stack.pop()
if root is None:
continue
if is_visited:
yield root.val
else:
stack.append((root.right, False))
stack.append((root, True))
stack.append((root.left, False))
yield None
result = []
left_gen, right_gen = inorder_gen(root1), inorder_gen(root2)
left, right = next(left_gen), next(right_gen)
while left is not None or right is not None:
if right is None or (left is not None and left < right):
result.append(left)
left = next(left_gen)
else:
result.append(right)
right = next(right_gen)
return result
161
search-a-2d-matrix.py
# Write an efficient algorithm that searches for a value in an m x n matrix.
# This matrix has the following properties:
#
#
# Integers in each row are sorted from left to right.
# The first integer of each row is greater than the last integer of the
# previous row.
#
#
# Example 1:
#
# Input:
# matrix = [
# [1, 3, 5, 7],
# [10, 11, 16, 20],
# [23, 30, 34, 50]
# ]
# target = 3
# Output: true
#
#
# Example 2:
#
# Input:
# matrix = [
# [1, 3, 5, 7],
# [10, 11, 16, 20],
# [23, 30, 34, 50]
# ]
# target = 13
# Output: false# Time: O(logm + logn)
# Space: O(1)
class Solution(object):
def searchMatrix(self, matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
if not matrix:
return False
m, n = len(matrix), len(matrix[0])
left, right = 0, m * n
while left < right:
mid = left + (right - left) / 2
if matrix[mid / n][mid % n] >= target:
right = mid
else:
left = mid + 1
162
find-all-anagrams-in-a-string.py
# Given a string s and a non-empty string p, find all the start indices of p's
# anagrams in s.
#
# Strings consists of lowercase English letters only and the length of both
# strings s and p will not be larger than 20,100.
#
# The order of output does not matter.
#
# Example 1:
# Input:
# s: "cbaebabacd" p: "abc"
#
# Output:
# [0, 6]
#
# Explanation:
# The substring with start index = 0 is "cba", which is an anagram of "abc".
# The substring with start index = 6 is "bac", which is an anagram of "abc".
#
#
#
# Example 2:
# Input:
# s: "abab" p: "ab"
#
# Output:
# [0, 1, 2]
#
# Explanation:
# The substring with start index = 0 is "ab", which is an anagram of "ab".
# The substring with start index = 1 is "ba", which is an anagram of "ab".
# The substring with start index = 2 is "ab", which is an anagram of "ab".# Time: O(n)
# Space: O(1)
class Solution(object):
def findAnagrams(self, s, p):
"""
:type s: str
:type p: str
:rtype: List[int]
"""
result = []
cnts = [0] * 26
for c in p:
cnts[ord(c) - ord('a')] += 1
left, right = 0, 0
while right < len(s):
cnts[ord(s[right]) - ord('a')] -= 1
while left <= right and cnts[ord(s[right]) - ord('a')] < 0:
cnts[ord(s[left]) - ord('a')] += 1
left += 1
if right - left + 1 == len(p):
result.append(left)
right += 1
return result
163
fizz-buzz-multithreaded.py
# Write a program that outputs the string representation of numbers from 1 to n,
# however:
#
#
# If the number is divisible by 3, output "fizz".
# If the number is divisible by 5, output "buzz".
# If the number is divisible by both 3 and 5, output "fizzbuzz".
#
#
# For example, for n = 15, we output: 1, 2, fizz, 4, buzz, fizz, 7, 8, fizz,
# buzz, 11, fizz, 13, 14, fizzbuzz.
#
# Suppose you are given the following code:
#
# class FizzBuzz {
# public FizzBuzz(int n) { ... } // constructor
# public void fizz(printFizz) { ... } // only output "fizz"
# public void buzz(printBuzz) { ... } // only output "buzz"
# public void fizzbuzz(printFizzBuzz) { ... } // only output "fizzbuzz"
# public void number(printNumber) { ... } // only output the numbers
# }
#
# Implement a multithreaded version of FizzBuzz with four threads. The same
# instance of FizzBuzz will be passed to four different threads:
#
#
# Thread A will call fizz() to check for divisibility of 3 and
# outputs fizz.
# Thread B will call buzz() to check for divisibility of 5 and
# outputs buzz.
# Thread C will call fizzbuzz() to check for divisibility of 3 and 5 and
# outputs fizzbuzz.
# Thread D will call number() which should only output the numbers.# Time: O(n)
# Space: O(1)
import threading
class FizzBuzz(object):
def __init__(self, n):
self.__n = n
self.__curr = 0
self.__cv = threading.Condition()
164
# printBuzz() outputs "buzz"
def buzz(self, printBuzz):
"""
:type printBuzz: method
:rtype: void
"""
for i in xrange(1, self.__n+1):
with self.__cv:
while self.__curr % 4 != 1:
self.__cv.wait()
self.__curr += 1
if i % 3 != 0 and i % 5 == 0:
printBuzz()
self.__cv.notify_all()
165
minimum-genetic-mutation.py
# A gene string can be represented by an 8-character long string, with choices
# from "A", "C", "G", "T".
#
# Suppose we need to investigate about a mutation (mutation from "start" to
# "end"), where ONE mutation is defined as ONE single character changed in the
# gene string.
#
# For example, "AACCGGTT" -> "AACCGGTA" is 1 mutation.
#
# Also, there is a given gene "bank", which records all the valid gene
# mutations. A gene must be in the bank to make it a valid gene string.
#
# Now, given 3 things - start, end, bank, your task is to determine what is the
# minimum number of mutations needed to mutate from "start" to "end". If there is
# no such a mutation, return -1.
#
# Note:
#
#
# Starting point is assumed to be valid, so it might not be included in
# the bank.
# If multiple mutations are needed, all mutations during in the sequence
# must be valid.
# You may assume start and end string is not the same.
#
#
#
#
# Example 1:
#
# start: "AACCGGTT"
# end: "AACCGGTA"
# bank: ["AACCGGTA"]
#
# return: 1
#
#
#
#
# Example 2:
#
# start: "AACCGGTT"
# end: "AAACGGTA"
# bank: ["AACCGGTA", "AACCGCTA", "AAACGGTA"]
#
# return: 2
#
#
#
#
# Example 3:
#
# start: "AAAAACCC"
# end: "AACCCCCC"
# bank: ["AAAACCCC", "AAACCCCC", "AACCCCCC"]
#
# return: 3# Time: O(n * b), n is the length of gene string, b is size of bank
# Space: O(b)
166
from collections import deque
class Solution(object):
def minMutation(self, start, end, bank):
"""
:type start: str
:type end: str
:type bank: List[str]
:rtype: int
"""
lookup = {}
for b in bank:
lookup[b] = False
q = deque([(start, 0)])
while q:
cur, level = q.popleft()
if cur == end:
return level
for i in xrange(len(cur)):
for c in ['A', 'T', 'C', 'G']:
if cur[i] == c:
continue
return -1
167
alphabet-board-path.py
# On an alphabet board, we start at position (0, 0), corresponding to
# character board[0][0].
#
# Here, board = ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"], as shown in
# the diagram below.
#
#
#
# We may make the following moves:
#
#
# 'U' moves our position up one row, if the position exists on the board;
# 'D' moves our position down one row, if the position exists on the
# board;
# 'L' moves our position left one column, if the position exists on the
# board;
# 'R' moves our position right one column, if the position exists on the
# board;
# '!' adds the character board[r][c] at our current position (r, c) to
# the answer.
#
#
# (Here, the only positions that exist on the board are positions with letters
# on them.)
#
# Return a sequence of moves that makes our answer equal to target in the
# minimum number of moves. You may return any path that does so.
#
#
# Example 1:
# Input: target = "leet"
# Output: "DDR!UURRR!!DDD!"
# Example 2:
# Input: target = "code"
# Output: "RR!DDRR!UUL!R!"
#
#
# Constraints:
#
#
# 1 <= target.length <= 100
# target consists only of English lowercase letters.# Time: O(n)
# Space: O(1)
class Solution(object):
def alphabetBoardPath(self, target):
"""
:type target: str
:rtype: str
"""
x, y = 0, 0
result = []
for c in target:
y1, x1 = divmod(ord(c)-ord('a'), 5)
result.append('U' * max(y-y1, 0))
result.append('L' * max(x-x1, 0))
result.append('R' * max(x1-x, 0))
result.append('D' * max(y1-y, 0))
168
result.append('!')
x, y = x1, y1
return "".join(result)
169
pancake-sorting.py
# Given an array of integers A, We need to sort the array performing a series of
# pancake flips.
#
# In one pancake flip we do the following steps:
#
#
# Choose an integer k where 0 <= k < A.length.
# Reverse the sub-array A[0...k].
#
#
# For example, if A = [3,2,1,4] and we performed a pancake flip choosing k = 2,
# we reverse the sub-array [3,2,1], so A = [1,2,3,4] after the pancake flip at k =
# 2.
#
# Return an array of the k-values of the pancake flips that should be performed
# in order to sort A. Any valid answer that sorts the array within 10 * A.length
# flips will be judged as correct.
#
#
# Example 1:
#
# Input: A = [3,2,4,1]
# Output: [4,2,4,3]
# Explanation:
# We perform 4 pancake flips, with k values 4, 2, 4, and 3.
# Starting state: A = [3, 2, 4, 1]
# After 1st flip (k = 4): A = [1, 4, 2, 3]
# After 2nd flip (k = 2): A = [4, 1, 2, 3]
# After 3rd flip (k = 4): A = [3, 2, 1, 4]
# After 4th flip (k = 3): A = [1, 2, 3, 4], which is sorted.
# Notice that we return an array of the chosen k values of the pancake flips.
#
#
# Example 2:
#
# Input: A = [1,2,3]
# Output: []
# Explanation: The input is already sorted, so there is no need to flip
# anything.
# Note that other answers, such as [3, 3], would also be accepted.
#
#
#
# Constraints:
#
#
# 1 <= A.length <= 100
# 1 <= A[i] <= A.length
# All integers in A are unique (i.e. A is a permutation of the integers
# from 1 to A.length).# Time: O(n^2)
# Space: O(1)
class Solution(object):
def pancakeSort(self, A):
"""
:type A: List[int]
:rtype: List[int]
"""
170
def reverse(l, begin, end):
for i in xrange((end-begin) // 2):
l[begin+i], l[end-1-i] = l[end-1-i], l[begin+i]
result = []
for n in reversed(xrange(1, len(A)+1)):
i = A.index(n)
reverse(A, 0, i+1)
result.append(i+1)
reverse(A, 0, n)
result.append(n)
return result
171
01-matrix.py
# Given a matrix consists of 0 and 1, find the distance of the nearest 0 for
# each cell.
#
# The distance between two adjacent cells is 1.
#
#
#
# Example 1:
#
# Input:
# [[0,0,0],
# [0,1,0],
# [0,0,0]]
#
# Output:
# [[0,0,0],
# [0,1,0],
# [0,0,0]]
#
#
# Example 2:
#
# Input:
# [[0,0,0],
# [0,1,0],
# [1,1,1]]
#
# Output:
# [[0,0,0],
# [0,1,0],
# [1,2,1]]
#
#
#
#
# Note:
#
#
# The number of elements of the given matrix will not exceed 10,000.
# There are at least one 0 in the given matrix.
# The cells are adjacent in only four directions: up, down, left and
# right.# Time: O(m * n)
# Space: O(m * n)
import collections
class Solution(object):
def updateMatrix(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[List[int]]
"""
queue = collections.deque()
for i in xrange(len(matrix)):
for j in xrange(len(matrix[0])):
if matrix[i][j] == 0:
queue.append((i, j))
172
else:
matrix[i][j] = float("inf")
return matrix
# Time: O(m * n)
# Space: O(m * n)
# dp solution
class Solution2(object):
def updateMatrix(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[List[int]]
"""
dp = [[float("inf")]*len(matrix[0]) for _ in xrange(len(matrix))]
for i in xrange(len(matrix)):
for j in xrange(len(matrix[i])):
if matrix[i][j] == 0:
dp[i][j] = 0
else:
if i > 0:
dp[i][j] = min(dp[i][j], dp[i-1][j]+1)
if j > 0:
dp[i][j] = min(dp[i][j], dp[i][j-1]+1)
for i in reversed(xrange(len(matrix))):
for j in reversed(xrange(len(matrix[i]))):
if matrix[i][j] == 0:
dp[i][j] = 0
else:
if i < len(matrix)-1:
dp[i][j] = min(dp[i][j], dp[i+1][j]+1)
if j < len(matrix[i])-1:
dp[i][j] = min(dp[i][j], dp[i][j+1]+1)
return dp
173
maximum-product-subarray.py
# Given an integer array nums, find the contiguous subarray within an array
# (containing at least one number) which has the largest product.
#
# Example 1:
#
# Input: [2,3,-2,4]
# Output: 6
# Explanation: [2,3] has the largest product 6.
#
#
# Example 2:
#
# Input: [-2,0,-1]
# Output: 0
# Explanation: The result cannot be 2, because [-2,-1] is not a subarray.# Time: O(n)
# Space: O(1)
class Solution(object):
# @param A, a list of integers
# @return an integer
def maxProduct(self, A):
global_max, local_max, local_min = float("-inf"), 1, 1
for x in A:
local_max, local_min = max(x, local_max * x, local_min * x), min(x, local_max * x, local_min * x)
global_max = max(global_max, local_max)
return global_max
class Solution2(object):
# @param A, a list of integers
# @return an integer
def maxProduct(self, A):
global_max, local_max, local_min = float("-inf"), 1, 1
for x in A:
local_max = max(1, local_max)
if x > 0:
local_max, local_min = local_max * x, local_min * x
else:
local_max, local_min = local_min * x, local_max * x
global_max = max(global_max, local_max)
return global_max
174
distant-barcodes.py
# Example 2:
#
# Input: [1,1,1,1,2,2,3,3]
# Output: [1,3,1,3,2,1,2,1]# Time: O(klogk), k is the number of distinct barcodes
# Space: O(k)
import collections
class Solution(object):
def rearrangeBarcodes(self, barcodes):
"""
:type barcodes: List[int]
:rtype: List[int]
"""
cnts = collections.Counter(barcodes)
sorted_cnts = [[v, k] for k, v in cnts.iteritems()]
sorted_cnts.sort(reverse=True)
i = 0
for v, k in sorted_cnts:
for _ in xrange(v):
barcodes[i] = k
i += 2
if i >= len(barcodes):
i = 1
return barcodes
175
binary-subarrays-with-sum.py
# In an array A of 0s and 1s, how many non-empty subarrays have sum S?
#
#
#
# Example 1:
#
# Input: A = [1,0,1,0,1], S = 2
# Output: 4
# Explanation:
# The 4 subarrays are bolded below:
# [1,0,1,0,1]
# [1,0,1,0,1]
# [1,0,1,0,1]
# [1,0,1,0,1]
#
#
#
#
# Note:
#
#
# A.length <= 30000
# 0 <= S <= A.length
# A[i] is either 0 or 1.# Time: O(n)
# Space: O(1)
176
delete-node-in-a-bst.py
# Given a root node reference of a BST and a key, delete the node with the given
# key in the BST. Return the root node reference (possibly updated) of the BST.
#
# Basically, the deletion can be divided into two stages:
#
# Search for a node to remove.
# If the node is found, delete the node.
#
#
#
# Note: Time complexity should be O(height of tree).
#
# Example:
# root = [5,3,6,2,4,null,7]
# key = 3
#
# 5
# / \
# 3 6
# / \ \
# 2 4 7
#
# Given key to delete is 3. So we find the node with value 3 and delete it.
#
# One valid answer is [5,4,6,2,null,null,7], shown in the following BST.
#
# 5
# / \
# 4 6
# / \
# 2 7
#
# Another valid answer is [5,2,6,null,4,null,7].
#
# 5
# / \
# 2 6
# \ \
# 4 7# Time: O(h)
# Space: O(h)
class Solution(object):
def deleteNode(self, root, key):
"""
:type root: TreeNode
:type key: int
:rtype: TreeNode
"""
if not root:
return root
177
del root
return right
elif not root.right:
left = root.left
del root
return left
else:
successor = root.right
while successor.left:
successor = successor.left
root.val = successor.val
root.right = self.deleteNode(root.right, successor.val)
return root
178
random-pick-index.py
# Given an array of integers with possible duplicates, randomly output the index
# of a given target number. You can assume that the given target number must exist
# in the array.
#
# Note:
#
# The array size can be very large. Solution that uses too much extra space will
# not pass the judge.
#
# Example:
#
# int[] nums = new int[] {1,2,3,3,3};
# Solution solution = new Solution(nums);
#
# // pick(3) should return either index 2, 3, or 4 randomly. Each index should
# have equal probability of returning.
# solution.pick(3);
#
# // pick(1) should return 0. Since in the array only nums[0] is equal to 1.
# solution.pick(1);# Time: O(n)
# Space: O(1)
class Solution(object):
179
word-break.py
# Given a non-empty string s and a dictionary wordDict containing a list of non-
# empty words, determine if s can be segmented into a space-separated sequence of
# one or more dictionary words.
#
# Note:
#
#
# The same word in the dictionary may be reused multiple times in the
# segmentation.
# You may assume the dictionary does not contain duplicate words.
#
#
# Example 1:
#
# Input: s = "leetcode", wordDict = ["leet", "code"]
# Output: true
# Explanation: Return true because "leetcode" can be segmented as "leet code".
#
#
# Example 2:
#
# Input: s = "applepenapple", wordDict = ["apple", "pen"]
# Output: true
# Explanation: Return true because "applepenapple" can be segmented as "apple
# pen apple".
# Note that you are allowed to reuse a dictionary word.
#
#
# Example 3:
#
# Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
# Output: false# Time: O(n * l^2)
# Space: O(n)
class Solution(object):
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: Set[str]
:rtype: bool
"""
n = len(s)
max_len = 0
for string in wordDict:
max_len = max(max_len, len(string))
return can_break[-1]
180
video-stitching.py
# You are given a series of video clips from a sporting event that lasted T
# seconds. These video clips can be overlapping with each other and have varied
# lengths.
#
# Each video clip clips[i] is an interval: it starts at time clips[i][0] and
# ends at time clips[i][1]. We can cut these clips into segments freely: for
# example, a clip [0, 7] can be cut into segments [0, 1] + [1, 3] + [3, 7].
#
# Return the minimum number of clips needed so that we can cut the clips into
# segments that cover the entire sporting event ([0, T]). If the task is
# impossible, return -1.
#
#
#
# Example 1:
#
# Input: clips = [[0,2],[4,6],[8,10],[1,9],[1,5],[5,9]], T = 10
# Output: 3
# Explanation:
# We take the clips [0,2], [8,10], [1,9]; a total of 3 clips.
# Then, we can reconstruct the sporting event as follows:
# We cut [1,9] into segments [1,2] + [2,8] + [8,9].
# Now we have segments [0,2] + [2,8] + [8,10] which cover the sporting event [0,
# 10].
#
#
# Example 2:
#
# Input: clips = [[0,1],[1,2]], T = 5
# Output: -1
# Explanation:
# We can't cover [0,5] with only [0,1] and [1,2].
#
#
# Example 3:
#
# Input: clips = [[0,1],[6,8],[0,2],[5,6],[0,4],[0,3],[6,7],[1,3],[4,7],[1,4],[2
# ,5],[2,6],[3,4],[4,5],[5,7],[6,9]], T = 9
# Output: 3
# Explanation:
# We can take clips [0,4], [4,7], and [6,9].
#
#
# Example 4:
#
# Input: clips = [[0,4],[2,8]], T = 5
# Output: 2
# Explanation:
# Notice you can have extra video after the event ends.
#
#
#
# Constraints:
#
#
# 1 <= clips.length <= 100
# 0 <= clips[i][0] <= clips[i][1] <= 100
# 0 <= T <= 100# Time: O(nlogn)
181
# Space: O(1)
class Solution(object):
def videoStitching(self, clips, T):
"""
:type clips: List[List[int]]
:type T: int
:rtype: int
"""
result = 1
curr_reachable, reachable = 0, 0
clips.sort()
for left, right in clips:
if left > reachable:
break
elif left > curr_reachable:
curr_reachable = reachable
result += 1
reachable = max(reachable, right)
if reachable >= T:
return result
return -1
182
shortest-path-with-alternating-colors.py
# Consider a directed graph, with nodes labelled 0, 1, ..., n-1. In this graph,
# each edge is either red or blue, and there could be self-edges or parallel
# edges.
#
# Each [i, j] in red_edges denotes a red directed edge from node i to node j.
# Similarly, each [i, j] in blue_edges denotes a blue directed edge from node i to
# node j.
#
# Return an array answer of length n, where each answer[X] is the length of the
# shortest path from node 0 to node X such that the edge colors alternate along
# the path (or -1 if such a path doesn't exist).
#
#
# Example 1:
# Input: n = 3, red_edges = [[0,1],[1,2]], blue_edges = []
# Output: [0,1,-1]
# Example 2:
# Input: n = 3, red_edges = [[0,1]], blue_edges = [[2,1]]
# Output: [0,1,-1]
# Example 3:
# Input: n = 3, red_edges = [[1,0]], blue_edges = [[2,1]]
# Output: [0,-1,-1]
# Example 4:
# Input: n = 3, red_edges = [[0,1]], blue_edges = [[1,2]]
# Output: [0,1,2]
# Example 5:
# Input: n = 3, red_edges = [[0,1],[0,2]], blue_edges = [[1,0]]
# Output: [0,1,1]
#
#
# Constraints:
#
#
# 1 <= n <= 100
# red_edges.length <= 400
# blue_edges.length <= 400
# red_edges[i].length == blue_edges[i].length == 2
# 0 <= red_edges[i][j], blue_edges[i][j] < n# Time: O(n + e), e is the number of red and blue edges
# Space: O(n + e)
import collections
class Solution(object):
def shortestAlternatingPaths(self, n, red_edges, blue_edges):
"""
:type n: int
:type red_edges: List[List[int]]
:type blue_edges: List[List[int]]
:rtype: List[int]
"""
neighbors = [[set() for _ in xrange(2)] for _ in xrange(n)]
for i, j in red_edges:
neighbors[i][0].add(j)
for i, j in blue_edges:
neighbors[i][1].add(j)
INF = max(2*n-3, 0)+1
dist = [[INF, INF] for i in xrange(n)]
183
dist[0] = [0, 0]
q = collections.deque([(0, 0), (0, 1)])
while q:
i, c = q.popleft()
for j in neighbors[i][c]:
if dist[j][c] != INF:
continue
dist[j][c] = dist[i][1^c]+1
q.append((j, 1^c))
return [x if x != INF else -1 for x in map(min, dist)]
184
maximum-width-ramp.py
# Note:
#
#
# 2 <= A.length <= 50000
# 0 <= A[i] <= 50000# Time: O(n)
# Space: O(n)
class Solution(object):
def maxWidthRamp(self, A):
"""
:type A: List[int]
:rtype: int
"""
result = 0
s = []
for i in A:
if not s or A[s[-1]] > A[i]:
s.append(i)
for j in reversed(xrange(len(A))):
while s and A[s[-1]] <= A[j]:
result = max(result, j-s.pop())
return result
185
binary-search-tree-to-greater-sum-tree.py
# Note: This question is the same as 538: https://leetcode.com/problems/convert-
# bst-to-greater-tree/# Time: O(n)
# Space: O(h)
class Solution(object):
def bstToGst(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
def bstToGstHelper(root, prev):
if not root:
return root
bstToGstHelper(root.right, prev)
root.val += prev[0]
prev[0] = root.val
bstToGstHelper(root.left, prev)
return root
prev = [0]
return bstToGstHelper(root, prev)
186
nth-digit.py
# Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9,
# 10, 11, ...
#
# Note:
#
# n is positive and will fit within the range of a 32-bit signed integer (n <
# 231).
#
#
# Example 1:
# Input:
# 3
#
# Output:
# 3
#
#
#
# Example 2:
# Input:
# 11
#
# Output:
# 0
#
# Explanation:
# The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0,
# which is part of the number 10.# Time: O(logn)
# Space: O(1)
class Solution(object):
def findNthDigit(self, n):
"""
:type n: int
:rtype: int
"""
digit_len = 1
while n > digit_len * 9 * (10 ** (digit_len-1)):
n -= digit_len * 9 * (10 ** (digit_len-1))
digit_len += 1
return nth_digit
187
elimination-game.py
# There is a list of sorted integers from 1 to n. Starting from left to right,
# remove the first number and every other number afterward until you reach the end
# of the list.
#
# Repeat the previous step again, but this time from right to left, remove the
# right most number and every other number from the remaining numbers.
#
# We keep repeating the steps again, alternating left to right and right to
# left, until a single number remains.
#
# Find the last number that remains starting with a list of length n.
#
# Example:
# Input:
# n = 9,
# 1 2 3 4 5 6 7 8 9
# 2 4 6 8
# 2 6
# 6
#
# Output:
# 6# Time: O(logn)
# Space: O(1)
class Solution(object):
def lastRemaining(self, n):
"""
:type n: int
:rtype: int
"""
start, step, direction = 1, 2, 1
while n > 1:
start += direction * (step * (n/2) - step/2)
n /= 2
step *= 2
direction *= -1
return start
188
can-make-palindrome-from-substring.py
# Given a string s, we make queries on substrings of s.
#
# For each query queries[i] = [left, right, k], we may rearrange the substring
# s[left], ..., s[right], and then choose up to k of them to replace with any
# lowercase English letter.
#
# If the substring is possible to be a palindrome string after the operations
# above, the result of the query is true. Otherwise, the result is false.
#
# Return an array answer[], where answer[i] is the result of the i-th query
# queries[i].
#
# Note that: Each letter is counted individually for replacement so if for
# example s[left..right] = "aaa", and k = 2, we can only replace two of the
# letters. (Also, note that the initial string s is never modified by any query.)
#
#
# Example :
#
# Input: s = "abcda", queries = [[3,3,0],[1,2,0],[0,3,1],[0,3,2],[0,4,1]]
# Output: [true,false,false,true,true]
# Explanation:
# queries[0] : substring = "d", is palidrome.
# queries[1] : substring = "bc", is not palidrome.
# queries[2] : substring = "abcd", is not palidrome after replacing only 1
# character.
# queries[3] : substring = "abcd", could be changed to "abba" which is
# palidrome. Also this can be changed to "baab" first rearrange it "bacd" then
# replace "cd" with "ab".
# queries[4] : substring = "abcda", could be changed to "abcba" which is
# palidrome.
#
#
#
# Constraints:
#
#
# 1 <= s.length, queries.length <= 10^5
# 0 <= queries[i][0] <= queries[i][1] < s.length
# 0 <= queries[i][2] <= s.length
# s only contains lowercase English letters.# Time: O(m + n), m is the number of queries, n is the lengt
# Space: O(n)
import itertools
class Solution(object):
def canMakePaliQueries(self, s, queries):
"""
:type s: str
:type queries: List[List[int]]
:rtype: List[bool]
"""
CHARSET_SIZE = 26
curr, count = [0]*CHARSET_SIZE, [[0]*CHARSET_SIZE]
for c in s:
curr[ord(c)-ord('a')] += 1
count.append(curr[:])
189
return [sum((b-a)%2 for a, b in itertools.izip(count[left], count[right+1]))//2 <= k
for left, right, k in queries]
190
design-twitter.py
# Design a simplified version of Twitter where users can post tweets,
# follow/unfollow another user and is able to see the 10 most recent tweets in the
# user's news feed. Your design should support the following methods:
#
#
#
# postTweet(userId, tweetId): Compose a new tweet.
# getNewsFeed(userId): Retrieve the 10 most recent tweet ids in the user's news
# feed. Each item in the news feed must be posted by users who the user followed
# or by the user herself. Tweets must be ordered from most recent to least recent.
# follow(followerId, followeeId): Follower follows a followee.
# unfollow(followerId, followeeId): Follower unfollows a followee.
#
#
#
# Example:
# Twitter twitter = new Twitter();
#
# // User 1 posts a new tweet (id = 5).
# twitter.postTweet(1, 5);
#
# // User 1's news feed should return a list with 1 tweet id -> [5].
# twitter.getNewsFeed(1);
#
# // User 1 follows user 2.
# twitter.follow(1, 2);
#
# // User 2 posts a new tweet (id = 6).
# twitter.postTweet(2, 6);
#
# // User 1's news feed should return a list with 2 tweet ids -> [6, 5].
# // Tweet id 6 should precede tweet id 5 because it is posted after tweet id 5.
# twitter.getNewsFeed(1);
#
# // User 1 unfollows user 2.
# twitter.unfollow(1, 2);
#
# // User 1's news feed should return a list with 1 tweet id -> [5],
# // since user 1 is no longer following user 2.
# twitter.getNewsFeed(1);# Time: O(klogu), k is most recently number of tweets,
# u is the number of the user's following.
# Space: O(t + f), t is the total number of tweets,
# f is the total number of followings.
import collections
import heapq
class Twitter(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.__number_of_most_recent_tweets = 10
self.__followings = collections.defaultdict(set)
self.__messages = collections.defaultdict(list)
self.__time = 0
191
def postTweet(self, userId, tweetId):
"""
Compose a new tweet.
:type userId: int
:type tweetId: int
:rtype: void
"""
self.__time += 1
self.__messages[userId].append((self.__time, tweetId))
result = []
while max_heap and len(result) < self.__number_of_most_recent_tweets:
t, uid, curr = heapq.heappop(max_heap)
nxt = curr + 1
if nxt != len(self.__messages[uid]):
heapq.heappush(max_heap, (-self.__messages[uid][-(nxt+1)][0], uid, nxt))
result.append(self.__messages[uid][-(curr+1)][1])
return result
192
palindrome-partitioning.py
# Given a string s, partition s such that every substring of the partition is a
# palindrome.
#
# Return all possible palindrome partitioning of s.
#
# Example:
#
# Input: "aab"
# Output:
# [
# ["aa","b"],
# ["a","a","b"]
# ]# Time: O(n^2 ~ 2^n)
# Space: O(n^2)
class Solution(object):
# @param s, a string
# @return a list of lists of string
def partition(self, s):
n = len(s)
return sub_partition[0]
# Time: O(2^n)
# Space: O(n)
# recursive solution
class Solution2(object):
# @param s, a string
# @return a list of lists of string
def partition(self, s):
result = []
self.partitionRecu(result, [], s, 0)
return result
193
def isPalindrome(self, s):
for i in xrange(len(s) / 2):
if s[i] != s[-(i + 1)]:
return False
return True
194
rectangle-area.py
# Find the total area covered by two rectilinear rectangles in a 2D plane.
#
# Each rectangle is defined by its bottom left corner and top right corner as
# shown in the figure.
#
#
#
# Example:
#
# Input: A = -3, B = 0, C = 3, D = 4, E = 0, F = -1, G = 9, H = 2
# Output: 45
#
# Note:
#
# Assume that the total area is never beyond the maximum possible value of int.# Time: O(1)
# Space: O(1)
class Solution(object):
# @param {integer} A
# @param {integer} B
# @param {integer} C
# @param {integer} D
# @param {integer} E
# @param {integer} F
# @param {integer} G
# @param {integer} H
# @return {integer}
def computeArea(self, A, B, C, D, E, F, G, H):
return (D - B) * (C - A) + \
(G - E) * (H - F) - \
max(0, (min(C, G) - max(A, E))) * \
max(0, (min(D, H) - max(B, F)))
195
course-schedule-ii.py
# There are a total of n courses you have to take labelled from 0 to n - 1.
#
# Some courses may have prerequisites, for example, if prerequisites[i] = [ai,
# bi] this means you must take the course bi before the course ai.
#
# Given the total number of courses numCourses and a list of the prerequisite
# pairs, return the ordering of courses you should take to finish all courses.
#
# If there are many valid answers, return any of them. If it is impossible to
# finish all courses, return an empty array.
#
#
# Example 1:
#
# Input: numCourses = 2, prerequisites = [[1,0]]
# Output: [0,1]
# Explanation: There are a total of 2 courses to take. To take course 1 you
# should have finished course 0. So the correct course order is [0,1].
#
#
# Example 2:
#
# Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
# Output: [0,2,1,3]
# Explanation: There are a total of 4 courses to take. To take course 3 you
# should have finished both courses 1 and 2. Both courses 1 and 2 should be taken
# after you finished course 0.
# So one correct course order is [0,1,2,3]. Another correct ordering is
# [0,2,1,3].
#
#
# Example 3:
#
# Input: numCourses = 1, prerequisites = []
# Output: [0]
#
#
#
# Constraints:
#
#
# 1 <= numCourses <= 2000
# 0 <= prerequisites.length <= numCourses * (numCourses - 1)
# prerequisites[i].length == 2
# 0 <= ai, bi < numCourses
# ai != bi
# All the pairs [ai, bi] are distinct.from collections import defaultdict, deque
class Solution(object):
def findOrder(self, numCourses, prerequisites):
"""
:type numCourses: int
:type prerequisites: List[List[int]]
:rtype: List[int]
"""
res, zero_in_degree_queue = [], deque()
in_degree, out_degree = defaultdict(set), defaultdict(set)
196
for i, j in prerequisites:
in_degree[i].add(j)
out_degree[j].add(i)
for i in xrange(numCourses):
if i not in in_degree:
zero_in_degree_queue.append(i)
while zero_in_degree_queue:
prerequisite = zero_in_degree_queue.popleft()
res.append(prerequisite)
if prerequisite in out_degree:
for course in out_degree[prerequisite]:
in_degree[course].discard(prerequisite)
if not in_degree[course]:
zero_in_degree_queue.append(course)
del out_degree[prerequisite]
if out_degree:
return []
return res
197
car-pooling.py
# Example 2:
#
# Input: trips = [[2,1,5],[3,3,7]], capacity = 5
# Output: true
#
#
#
# Example 3:
#
# Input: trips = [[2,1,5],[3,5,7]], capacity = 3
# Output: true
#
#
#
# Example 4:
#
# Input: trips = [[3,2,7],[3,7,9],[8,3,9]], capacity = 11
# Output: true# Time: O(nlogn)
# Space: O(n)
class Solution(object):
def carPooling(self, trips, capacity):
"""
:type trips: List[List[int]]
:type capacity: int
:rtype: bool
"""
line = [x for num, start, end in trips for x in [[start, num], [end, -num]]]
line.sort()
for _, num in line:
capacity -= num
if capacity < 0:
return False
return True
198
maximum-nesting-depth-of-two-valid-parentheses-strings.py
# A string is a valid parentheses string (denoted VPS) if and only if it
# consists of "(" and ")" characters only, and:
#
#
# It is the empty string, or
# It can be written as AB (A concatenated with B), where A and B are
# VPS's, or
# It can be written as (A), where A is a VPS.
#
#
# We can similarly define the nesting depth depth(S) of any VPS S as follows:
#
#
# depth("") = 0
# depth(A + B) = max(depth(A), depth(B)), where A and B are VPS's
# depth("(" + A + ")") = 1 + depth(A), where A is a VPS.
#
#
# For example, "", "()()", and "()(()())" are VPS's (with nesting depths 0, 1,
# and 2), and ")(" and "(()" are not VPS's.
#
#
#
# Given a VPS seq, split it into two disjoint subsequences A and B, such that A
# and B are VPS's (and A.length + B.length = seq.length).
#
# Now choose any such A and B such that max(depth(A), depth(B)) is the minimum
# possible value.
#
# Return an answer array (of length seq.length) that encodes such a choice of A
# and B: answer[i] = 0 if seq[i] is part of A, else answer[i] = 1. Note that
# even though multiple answers may exist, you may return any of them.
#
#
# Example 1:
#
# Input: seq = "(()())"
# Output: [0,1,1,1,1,0]
#
#
# Example 2:
#
# Input: seq = "()(())()"
# Output: [0,0,0,1,1,0,1,1]
#
#
#
# Constraints:
#
#
# 1 <= seq.size <= 10000# Time: O(n)
# Space: O(1)
class Solution(object):
def maxDepthAfterSplit(self, seq):
"""
:type seq: str
:rtype: List[int]
199
"""
return [(i & 1) ^ (seq[i] == '(') for i, c in enumerate(seq)]
# Time: O(n)
# Space: O(1)
class Solution2(object):
def maxDepthAfterSplit(self, seq):
"""
:type seq: str
:rtype: List[int]
"""
A, B = 0, 0
result = [0]*len(seq)
for i, c in enumerate(seq):
point = 1 if c == '(' else -1
if (point == 1 and A <= B) or \
(point == -1 and A >= B):
A += point
else:
B += point
result[i] = 1
return result
200
maximum-level-sum-of-a-binary-tree.py
# Given the root of a binary tree, the level of its root is 1, the level of its
# children is 2, and so on.
#
# Return the smallest level X such that the sum of all the values of nodes at
# level X is maximal.
#
#
#
# Example 1:
#
#
#
# Input: [1,7,0,7,-8,null,null]
# Output: 2
# Explanation:
# Level 1 sum = 1.
# Level 2 sum = 7 + 0 = 7.
# Level 3 sum = 7 + -8 = -1.
# So we return the level with the maximum sum which is level 2.
#
#
#
#
# Note:
#
#
# The number of nodes in the given tree is between 1 and 10^4.
# -10^5 <= node.val <= 10^5# Time: O(n)
# Space: O(h)
import collections
# dfs solution
class Solution(object):
def maxLevelSum(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def dfs(node, i, level_sums):
if not node:
return
if i == len(level_sums):
level_sums.append(0)
level_sums[i] += node.val
dfs(node.left, i+1, level_sums)
dfs(node.right, i+1, level_sums)
level_sums = []
201
dfs(root, 0, level_sums)
return level_sums.index(max(level_sums))+1
# Time: O(n)
# Space: O(w)
# bfs solution
class Solution2(object):
def maxLevelSum(self, root):
"""
:type root: TreeNode
:rtype: int
"""
result, level, max_total = 0, 1, float("-inf")
q = collections.deque([root])
while q:
total = 0
for _ in xrange(len(q)):
node = q.popleft()
total += node.val
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
if total > max_total:
result, max_total = level, total
level += 1
return result
202
combination-sum.py
# Given a set of candidate numbers (candidates) (without duplicates) and a
# target number (target), find all unique combinations in candidates where the
# candidate numbers sums to target.
#
# The same repeated number may be chosen from candidates unlimited number of
# times.
#
# Note:
#
#
# All numbers (including target) will be positive integers.
# The solution set must not contain duplicate combinations.
#
#
# Example 1:
#
# Input: candidates = [2,3,6,7], target = 7,
# A solution set is:
# [
# [7],
# [2,2,3]
# ]
#
#
# Example 2:
#
# Input: candidates = [2,3,5], target = 8,
# A solution set is:
# [
# [2,2,2,2],
# [2,3,3],
# [3,5]
# ]
#
#
#
# Constraints:
#
#
# 1 <= candidates.length <= 30
# 1 <= candidates[i] <= 200
# Each element of candidate is unique.
# 1 <= target <= 500# Time: O(k * n^k)
# Space: O(k)
class Solution(object):
# @param candidates, a list of integers
# @param target, integer
# @return a list of lists of integers
def combinationSum(self, candidates, target):
result = []
self.combinationSumRecu(sorted(candidates), result, 0, [], target)
return result
203
intermediate.append(candidates[start])
self.combinationSumRecu(candidates, result, start, intermediate, target - candidates[start])
intermediate.pop()
start += 1
204
flip-string-to-monotone-increasing.py
# A string of '0's and '1's is monotone increasing if it consists of some number
# of '0's (possibly 0), followed by some number of '1's (also possibly 0.)
#
# We are given a string S of '0's and '1's, and we may flip any '0' to a '1' or
# a '1' to a '0'.
#
# Return the minimum number of flips to make S monotone increasing.
#
#
#
#
# Example 1:
#
# Input: "00110"
# Output: 1
# Explanation: We flip the last digit to get 00111.
#
#
#
# Example 2:
#
# Input: "010110"
# Output: 2
# Explanation: We flip to get 011111, or alternatively 000111.
#
#
#
# Example 3:
#
# Input: "00011000"
# Output: 2
# Explanation: We flip to get 00000000.
#
#
#
#
# Note:
#
#
# 1 <= S.length <= 20000
# S only consists of '0' and '1' characters.# Time: O(n)
# Space: O(1)
class Solution(object):
def minFlipsMonoIncr(self, S):
"""
:type S: str
:rtype: int
"""
flip0, flip1 = 0, 0
for c in S:
flip0 += int(c == '1')
flip1 = min(flip0, flip1 + int(c == '0'))
return flip1
205
grumpy-bookstore-owner.py
# Today, the bookstore owner has a store open for customers.length minutes.
# Every minute, some number of customers (customers[i]) enter the store, and all
# those customers leave after the end of that minute.
#
# On some minutes, the bookstore owner is grumpy. If the bookstore owner is
# grumpy on the i-th minute, grumpy[i] = 1, otherwise grumpy[i] = 0. When the
# bookstore owner is grumpy, the customers of that minute are not satisfied,
# otherwise they are satisfied.
#
# The bookstore owner knows a secret technique to keep themselves not grumpy for
# X minutes straight, but can only use it once.
#
# Return the maximum number of customers that can be satisfied throughout the
# day.
#
#
#
# Example 1:
#
# Input: customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3
# Output: 16
# Explanation: The bookstore owner keeps themselves not grumpy for the last 3
# minutes.
# The maximum number of customers that can be satisfied = 1 + 1 + 1 + 1 + 7 + 5
# = 16.
#
#
#
#
# Note:
#
#
# 1 <= X <= customers.length == grumpy.length <= 20000
# 0 <= customers[i] <= 1000
# 0 <= grumpy[i] <= 1# Time: O(n)
# Space: O(1)
class Solution(object):
def maxSatisfied(self, customers, grumpy, X):
"""
:type customers: List[int]
:type grumpy: List[int]
:type X: int
:rtype: int
"""
result, max_extra, extra = 0, 0, 0
for i in xrange(len(customers)):
result += 0 if grumpy[i] else customers[i]
extra += customers[i] if grumpy[i] else 0
if i >= X:
extra -= customers[i-X] if grumpy[i-X] else 0
max_extra = max(max_extra, extra)
return result + max_extra
206
lowest-common-ancestor-of-a-binary-tree.py
# Given a binary tree, find the lowest common ancestor (LCA) of two given nodes
# in the tree.
#
# According to the definition of LCA on Wikipedia: “The lowest common ancestor
# is defined between two nodes p and q as the lowest node in T that has both p and
# q as descendants (where we allow a node to be a descendant of itself).”
#
# Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]
#
#
#
# Example 1:
#
# Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
# Output: 3
# Explanation: The LCA of nodes 5 and 1 is 3.
#
#
# Example 2:
#
# Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
# Output: 5
# Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant
# of itself according to the LCA definition.
#
#
#
#
# Note:
#
#
# All of the nodes' values will be unique.
# p and q are different and both values will exist in the binary tree.# Time: O(n)
# Space: O(h)
class Solution(object):
# @param {TreeNode} root
# @param {TreeNode} p
# @param {TreeNode} q
# @return {TreeNode}
def lowestCommonAncestor(self, root, p, q):
if root in (None, p, q):
return root
207
spiral-matrix-iii.py
# Note:
#
#
# 1 <= R <= 100
# 1 <= C <= 100
# 0 <= r0 < R
# 0 <= c0 < C# Time: O(max(m, n)^2)
# Space: O(1)
class Solution(object):
def spiralMatrixIII(self, R, C, r0, c0):
"""
:type R: int
:type C: int
:type r0: int
:type c0: int
:rtype: List[List[int]]
"""
r, c = r0, c0
result = [[r, c]]
x, y, n, i = 0, 1, 0, 0
while len(result) < R*C:
r, c, i = r+x, c+y, i+1
if 0 <= r < R and 0 <= c < C:
result.append([r, c])
if i == n//2+1:
x, y, n, i = y, -x, n+1, 0
return result
208
robot-bounded-in-circle.py
# On an infinite plane, a robot initially stands at (0, 0) and faces north. The
# robot can receive one of three instructions:
#
#
# "G": go straight 1 unit;
# "L": turn 90 degrees to the left;
# "R": turn 90 degress to the right.
#
#
# The robot performs the instructions given in order, and repeats them forever.
#
# Return true if and only if there exists a circle in the plane such that the
# robot never leaves the circle.
#
#
#
# Example 1:
#
# Input: "GGLLGG"
# Output: true
# Explanation:
# The robot moves from (0,0) to (0,2), turns 180 degrees, and then returns to
# (0,0).
# When repeating these instructions, the robot remains in the circle of radius 2
# centered at the origin.
#
#
# Example 2:
#
# Input: "GG"
# Output: false
# Explanation:
# The robot moves north indefinitely.
#
#
# Example 3:
#
# Input: "GL"
# Output: true
# Explanation:
# The robot moves from (0, 0) -> (0, 1) -> (-1, 1) -> (-1, 0) -> (0, 0) -> ...
#
#
#
#
# Note:
#
#
# 1 <= instructions.length <= 100
# instructions[i] is in {'G', 'L', 'R'}# Time: O(n)
# Space: O(1)
class Solution(object):
def isRobotBounded(self, instructions):
"""
:type instructions: str
:rtype: bool
"""
209
directions = [[ 1, 0], [0, -1], [-1, 0], [0, 1]]
x, y, i = 0, 0, 0
for instruction in instructions:
if instruction == 'R':
i = (i+1) % 4;
elif instruction == 'L':
i = (i-1) % 4;
else:
x += directions[i][0]
y += directions[i][1]
return (x == 0 and y == 0) or i > 0
210
super-pow.py
# Your task is to calculate ab mod 1337 where a is a positive integer and b is
# an extremely large positive integer given in the form of an array.
#
# Example 1:
#
#
# Input: a = 2, b = [3]
# Output: 8
#
#
#
# Example 2:
#
# Input: a = 2, b = [1,0]
# Output: 1024# Time: O(n), n is the size of b.
# Space: O(1)
class Solution(object):
def superPow(self, a, b):
"""
:type a: int
:type b: List[int]
:rtype: int
"""
def myPow(a, n, b):
result = 1
x = a % b
while n:
if n & 1:
result = result * x % b
n >>= 1
x = x * x % b
return result % b
result = 1
for digit in b:
result = myPow(result, 10, 1337) * myPow(a, digit, 1337) % 1337
return result
211
find-duplicate-subtrees.py
# Given the root of a binary tree, return all duplicate subtrees.
#
# For each kind of duplicate subtrees, you only need to return the root node of
# any one of them.
#
# Two trees are duplicate if they have the same structure with the same node
# values.
#
#
# Example 1:
#
# Input: root = [1,2,3,4,null,2,4,null,null,4]
# Output: [[2,4],[4]]
#
#
# Example 2:
#
# Input: root = [2,1,1]
# Output: [[1]]
#
#
# Example 3:
#
# Input: root = [2,2,2,3,null,3,null]
# Output: [[2,3],[3]]
#
#
#
# Constraints:
#
#
# The number of the nodes in the tree will be in the range [1, 10^4]
# -200 <= Node.val <= 200# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def findDuplicateSubtrees(self, root):
"""
:type root: TreeNode
:rtype: List[TreeNode]
"""
def getid(root, lookup, trees):
if root:
node_id = lookup[root.val, \
getid(root.left, lookup, trees), \
getid(root.right, lookup, trees)]
trees[node_id].append(root)
return node_id
trees = collections.defaultdict(list)
lookup = collections.defaultdict()
lookup.default_factory = lookup.__len__
getid(root, lookup, trees)
return [roots[0] for roots in trees.values() if len(roots) > 1]
212
# Time: O(n * h)
# Space: O(n * h)
class Solution2(object):
def findDuplicateSubtrees(self, root):
"""
:type root: TreeNode
:rtype: List[TreeNode]
"""
def postOrderTraversal(node, lookup, result):
if not node:
return ""
s = "(" + postOrderTraversal(node.left, lookup, result) + \
str(node.val) + \
postOrderTraversal(node.right, lookup, result) + \
")"
if lookup[s] == 1:
result.append(node)
lookup[s] += 1
return s
lookup = collections.defaultdict(int)
result = []
postOrderTraversal(root, lookup, result)
return result
213
insertion-sort-list.py
# Sort a linked list using insertion sort.
#
#
#
#
#
#
# A graphical example of insertion sort. The partial sorted list (black)
# initially contains only the first element in the list.
#
# With each iteration one element (red) is removed from the input data and
# inserted in-place into the sorted list
#
#
#
#
#
#
# Algorithm of Insertion Sort:
#
#
# Insertion sort iterates, consuming one input element each repetition,
# and growing a sorted output list.
# At each iteration, insertion sort removes one element from the input
# data, finds the location it belongs within the sorted list, and inserts it
# there.
# It repeats until no input elements remain.
#
#
#
#
# Example 1:
#
# Input: 4->2->1->3
# Output: 1->2->3->4
#
#
# Example 2:
#
# Input: -1->5->3->4->0
# Output: -1->0->3->4->5# Time: O(n ^ 2)
# Space: O(1)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{} -> {}".format(self.val, repr(self.next))
else:
return "Nil"
class Solution(object):
# @param head, a ListNode
# @return a ListNode
def insertionSortList(self, head):
214
if head is None or self.isSorted(head):
return head
dummy = ListNode(-2147483648)
dummy.next = head
cur, sorted_tail = head.next, head
while cur:
prev = dummy
while prev.next.val < cur.val:
prev = prev.next
if prev == sorted_tail:
cur, sorted_tail = cur.next, cur
else:
cur.next, prev.next, sorted_tail.next = prev.next, cur, cur.next
cur = sorted_tail.next
return dummy.next
215
mirror-reflection.py
# Example 1:
#
# Input: p = 2, q = 1
# Output: 2
# Explanation: The ray meets receptor 2 the first time it gets reflected back to
# the left wall.
#
#
#
# Note:
#
#
# 1 <= p <= 1000
# 0 <= q <= p# Time: O(1)
# Space: O(1)
class Solution(object):
def mirrorReflection(self, p, q):
"""
:type p: int
:type q: int
:rtype: int
"""
# explanation commented in the following solution
return 2 if (p & -p) > (q & -q) else 0 if (p & -p) < (q & -q) else 1
216
reverse-linked-list-ii.py
# Reverse a linked list from position m to n. Do it in one-pass.
#
# Note: 1 m n length of list.
#
# Example:
#
# Input: 1->2->3->4->5->NULL, m = 2, n = 4
# Output: 1->4->3->2->5->NULL# Time: O(n)
# Space: O(1)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{} -> {}".format(self.val, repr(self.next))
class Solution(object):
# @param head, a ListNode
# @param m, an integer
# @param n, an integer
# @return a ListNode
def reverseBetween(self, head, m, n):
diff, dummy, cur = n - m + 1, ListNode(-1), head
dummy.next = head
last_unswapped = dummy
while cur and m > 1:
cur, last_unswapped, m = cur.next, cur, m - 1
return dummy.next
217
validate-binary-tree-nodes.py
# You have n binary tree nodes numbered from 0 to n - 1 where node i has two
# children leftChild[i] and rightChild[i], return true if and only if all the
# given nodes form exactly one valid binary tree.
#
# If node i has no left child then leftChild[i] will equal -1, similarly for the
# right child.
#
# Note that the nodes have no values and that we only use the node numbers in
# this problem.
#
#
# Example 1:
#
#
#
# Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,-1,-1,-1]
# Output: true
#
#
# Example 2:
#
#
#
# Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,3,-1,-1]
# Output: false
#
#
# Example 3:
#
#
#
# Input: n = 2, leftChild = [1,0], rightChild = [-1,-1]
# Output: false
#
#
# Example 4:
#
#
#
# Input: n = 6, leftChild = [1,-1,-1,4,-1,-1], rightChild = [2,-1,-1,5,-1,-1]
# Output: false
#
#
#
# Constraints:
#
#
# 1 <= n <= 10^4
# leftChild.length == rightChild.length == n
# -1 <= leftChild[i], rightChild[i] <= n - 1# Time: O(n)
# Space: O(n)
class Solution(object):
def validateBinaryTreeNodes(self, n, leftChild, rightChild):
"""
:type n: int
:type leftChild: List[int]
:type rightChild: List[int]
218
:rtype: bool
"""
roots = set(range(n)) - set(leftChild) - set(rightChild)
if len(roots) != 1:
return False
root, = roots
stk = [root]
lookup = set([root])
while stk:
node = stk.pop()
for c in (leftChild[node], rightChild[node]):
if c < 0:
continue
if c in lookup:
return False
lookup.add(c)
stk.append(c)
return len(lookup) == n
219
unique-paths-ii.py
# A robot is located at the top-left corner of a m x n grid (marked 'Start' in
# the diagram below).
#
# The robot can only move either down or right at any point in time. The robot
# is trying to reach the bottom-right corner of the grid (marked 'Finish' in the
# diagram below).
#
# Now consider if some obstacles are added to the grids. How many unique paths
# would there be?
#
#
#
# An obstacle and empty space is marked as 1 and 0 respectively in the grid.
#
# Note: m and n will be at most 100.
#
# Example 1:
#
# Input:
# [
# [0,0,0],
# [0,1,0],
# [0,0,0]
# ]
# Output: 2
# Explanation:
# There is one obstacle in the middle of the 3x3 grid above.
# There are two ways to reach the bottom-right corner:
# 1. Right -> Right -> Down -> Down
# 2. Down -> Down -> Right -> Right# Time: O(m * n)
# Space: O(m + n)
class Solution(object):
# @param obstacleGrid, a list of lists of integers
# @return an integer
def uniquePathsWithObstacles(self, obstacleGrid):
"""
:type obstacleGrid: List[List[int]]
:rtype: int
"""
m, n = len(obstacleGrid), len(obstacleGrid[0])
ways = [0]*n
ways[0] = 1
for i in xrange(m):
if obstacleGrid[i][0] == 1:
ways[0] = 0
for j in xrange(n):
if obstacleGrid[i][j] == 1:
ways[j] = 0
elif j>0:
ways[j] += ways[j-1]
return ways[-1]
220
longest-absolute-file-path.py
# Suppose we have the file system represented in the following picture:
#
#
#
# We will represent the file system as a string where "\n\t" mean a subdirectory
# of the main directory, "\n\t\t" means a subdirectory of the subdirectory of the
# main directory and so on. Each folder will be represented as a string of letters
# and/or digits. Each file will be in the form "s1.s2" where s1 and s2 are strings
# of letters and/or digits.
#
# For example, the file system above is represented as "dir\n\tsubdir1\n\t\tfile
# 1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext".
#
# Given a string input representing the file system in the explained format,
# return the length of the longest absolute path to a file in the abstracted file
# system. If there is no file in the system, return 0.
#
#
# Example 1:
#
# Input: input = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext"
# Output: 20
# Explanation: We have only one file and its path is "dir/subdir2/file.ext" of
# length 20.
# The path "dir/subdir1" doesn't contain any files.
#
#
# Example 2:
#
# Input: input = "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\t
# subsubdir2\n\t\t\tfile2.ext"
# Output: 32
# Explanation: We have two files:
# "dir/subdir1/file1.ext" of length 21
# "dir/subdir2/subsubdir2/file2.ext" of length 32.
# We return 32 since it is the longest path.
#
#
# Example 3:
#
# Input: input = "a"
# Output: 0
# Explanation: We don't have any files.
#
#
#
# Constraints:
#
#
# 1 <= input.length <= 104
# input may contain lower-case or upper-case English letters, a new line
# character '\n', a tab character '\t', a dot '.', a space ' ' or digits.# Time: O(n)
# Space: O(d), d is the max depth of the paths
class Solution(object):
def lengthLongestPath(self, input):
"""
:type input: str
221
:rtype: int
"""
def split_iter(s, tok):
start = 0
for i in xrange(len(s)):
if s[i] == tok:
yield s[start:i]
start = i + 1
yield s[start:]
max_len = 0
path_len = {0: 0}
for line in split_iter(input, '\n'):
name = line.lstrip('\t')
depth = len(line) - len(name)
if '.' in name:
max_len = max(max_len, path_len[depth] + len(name))
else:
path_len[depth + 1] = path_len[depth] + len(name) + 1
return max_len
222
vowel-spellchecker.py
# Given a wordlist, we want to implement a spellchecker that converts a query
# word into a correct word.
#
# For a given query word, the spell checker handles two categories of spelling
# mistakes:
#
#
# Capitalization: If the query matches a word in the wordlist (case-
# insensitive), then the query word is returned with the same case as the case in
# the wordlist.
#
#
# Example: wordlist = ["yellow"], query = "YellOw": correct =
# "yellow"
# Example: wordlist = ["Yellow"], query = "yellow": correct =
# "Yellow"
# Example: wordlist = ["yellow"], query = "yellow": correct =
# "yellow"
#
#
# Vowel Errors: If after replacing the vowels ('a', 'e', 'i', 'o', 'u') of
# the query word with any vowel individually, it matches a word in the wordlist
# (case-insensitive), then the query word is returned with the same case as the
# match in the wordlist.
#
# Example: wordlist = ["YellOw"], query = "yollow": correct =
# "YellOw"
# Example: wordlist = ["YellOw"], query = "yeellow": correct = ""
# (no match)
# Example: wordlist = ["YellOw"], query = "yllw": correct = "" (no
# match)
#
#
#
#
# In addition, the spell checker operates under the following precedence rules:
#
#
# When the query exactly matches a word in the wordlist (case-sensitive),
# you should return the same word back.
# When the query matches a word up to capitlization, you should return the
# first such match in the wordlist.
# When the query matches a word up to vowel errors, you should return the
# first such match in the wordlist.
# If the query has no matches in the wordlist, you should return the empty
# string.
#
#
# Given some queries, return a list of words answer, where answer[i] is the
# correct word for query = queries[i].
#
#
#
# Example 1:
#
# Input: wordlist = ["KiTe","kite","hare","Hare"], queries =
# ["kite","Kite","KiTe","Hare","HARE","Hear","hear","keti","keet","keto"]
# Output: ["kite","KiTe","KiTe","Hare","hare","","","KiTe","","KiTe"]
223
#
#
#
# Note:
#
#
# 1 <= wordlist.length <= 5000
# 1 <= queries.length <= 5000
# 1 <= wordlist[i].length <= 7
# 1 <= queries[i].length <= 7
# All strings in wordlist and queries consist only of english letters.# Time: O(n)
# Space: O(w)
class Solution(object):
def spellchecker(self, wordlist, queries):
"""
:type wordlist: List[str]
:type queries: List[str]
:rtype: List[str]
"""
vowels = set(['a', 'e', 'i', 'o', 'u'])
def todev(word):
return "".join('*' if c.lower() in vowels else c.lower()
for c in word)
words = set(wordlist)
caps = {}
vows = {}
def check(query):
if query in words:
return query
lower = query.lower()
if lower in caps:
return caps[lower]
devow = todev(lower)
if devow in vows:
return vows[devow]
return ""
return map(check, queries)
224
shuffle-an-array.py
# Shuffle a set of numbers without duplicates.
#
#
# Example:
# // Init an array with set 1, 2, and 3.
# int[] nums = {1,2,3};
# Solution solution = new Solution(nums);
#
# // Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3]
# must equally likely to be returned.
# solution.shuffle();
#
# // Resets the array back to its original configuration [1,2,3].
# solution.reset();
#
# // Returns the random shuffling of array [1,2,3].
# solution.shuffle();# Time: O(n)
# Space: O(n)
import random
class Solution(object):
def reset(self):
"""
Resets the array to its original configuration and return it.
:rtype: List[int]
"""
return self.__nums
def shuffle(self):
"""
Returns a random shuffling of the array.
:rtype: List[int]
"""
nums = list(self.__nums)
for i in xrange(len(nums)):
j = random.randint(i, len(nums)-1)
nums[i], nums[j] = nums[j], nums[i]
return nums
225
minimum-falling-path-sum.py
# Given a square array of integers A, we want the minimum sum of a falling path
# through A.
#
# A falling path starts at any element in the first row, and chooses one element
# from each row. The next row's choice must be in a column that is different from
# the previous row's column by at most one.
#
#
#
# Example 1:
#
# Input: [[1,2,3],[4,5,6],[7,8,9]]
# Output: 12
# Explanation:
# The possible falling paths are:
#
#
#
# [1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9]
# [2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9]
# [3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9]
#
#
# The falling path with the smallest sum is [1,4,7], so the answer is 12.
#
#
# Constraints:
#
#
# 1 <= A.length == A[0].length <= 100
# -100 <= A[i][j] <= 100# Time: O(n^2)
# Space: O(1)
class Solution(object):
def minFallingPathSum(self, A):
"""
:type A: List[List[int]]
:rtype: int
"""
for i in xrange(1, len(A)):
for j in xrange(len(A[i])):
A[i][j] += min(A[i-1][max(j-1, 0):j+2])
return min(A[-1])
226
boats-to-save-people.py
# The i-th person has weight people[i], and each boat can carry a maximum weight
# of limit.
#
# Each boat carries at most 2 people at the same time, provided the sum of
# the weight of those people is at most limit.
#
# Return the minimum number of boats to carry every given person. (It is
# guaranteed each person can be carried by a boat.)
#
#
#
#
# Example 1:
#
# Input: people = [1,2], limit = 3
# Output: 1
# Explanation: 1 boat (1, 2)
#
#
#
# Example 2:
#
# Input: people = [3,2,2,1], limit = 3
# Output: 3
# Explanation: 3 boats (1, 2), (2) and (3)
#
#
#
# Example 3:
#
# Input: people = [3,5,3,4], limit = 5
# Output: 4
# Explanation: 4 boats (3), (3), (4), (5)
#
# Note:
#
#
# 1 <= people.length <= 50000
# 1 <= people[i] <= limit <= 30000# Time: O(nlogn)
# Space: O(n)
class Solution(object):
def numRescueBoats(self, people, limit):
"""
:type people: List[int]
:type limit: int
:rtype: int
"""
people.sort()
result = 0
left, right = 0, len(people)-1
while left <= right:
result += 1
if people[left] + people[right] <= limit:
left += 1
right -= 1
return result
227
sum-root-to-leaf-numbers.py
# Given a binary tree containing digits from 0-9 only, each root-to-leaf path
# could represent a number.
#
# An example is the root-to-leaf path 1->2->3 which represents the number 123.
#
# Find the total sum of all root-to-leaf numbers.
#
# Note: A leaf is a node with no children.
#
# Example:
#
# Input: [1,2,3]
# 1
# / \
# 2 3
# Output: 25
# Explanation:
# The root-to-leaf path 1->2 represents the number 12.
# The root-to-leaf path 1->3 represents the number 13.
# Therefore, sum = 12 + 13 = 25.
#
# Example 2:
#
# Input: [4,9,0,5,1]
# 4
# / \
# 9 0
# / \
# 5 1
# Output: 1026
# Explanation:
# The root-to-leaf path 4->9->5 represents the number 495.
# The root-to-leaf path 4->9->1 represents the number 491.
# The root-to-leaf path 4->0 represents the number 40.
# Therefore, sum = 495 + 491 + 40 = 1026.# Time: O(n)
# Space: O(h), h is height of binary tree
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
# @param root, a tree node
# @return an integer
def sumNumbers(self, root):
return self.sumNumbersRecu(root, 0)
228
different-ways-to-add-parentheses.py
# Given a string of numbers and operators, return all possible results from
# computing all the different possible ways to group numbers and operators. The
# valid operators are +, - and *.
#
# Example 1:
#
# Input: "2-1-1"
# Output: [0, 2]
# Explanation:
# ((2-1)-1) = 0
# (2-(1-1)) = 2
#
# Example 2:
#
# Input: "2*3-4*5"
# Output: [-34, -14, -10, -10, 10]
# Explanation:
# (2*(3-(4*5))) = -34
# ((2*3)-(4*5)) = -14
# ((2*(3-4))*5) = -10
# (2*((3-4)*5)) = -10
# (((2*3)-4)*5) = 10# Time: O(n * 4^n / n^(3/2)) ~= n * Catalan numbers = n * (C(2n, n) - C(2n, n - 1)),
# due to the size of the results is Catalan numbers,
# and every way of evaluation is the length of the string,
# so the time complexity is at most n * Catalan numbers.
# Space: O(n * 4^n / n^(3/2)), the cache size of lookup is at most n * Catalan numbers.
import operator
import re
class Solution(object):
# @param {string} input
# @return {integer[]}
def diffWaysToCompute(self, input):
tokens = re.split('(\D)', input)
nums = map(int, tokens[::2])
ops = map({'+': operator.add, '-': operator.sub, '*': operator.mul}.get, tokens[1::2])
lookup = [[None for _ in xrange(len(nums))] for _ in xrange(len(nums))]
class Solution2(object):
# @param {string} input
# @return {integer[]}
def diffWaysToCompute(self, input):
lookup = [[None for _ in xrange(len(input) + 1)] for _ in xrange(len(input) + 1)]
229
ops = {'+': operator.add, '-': operator.sub, '*': operator.mul}
if not result:
result = [int(input[left:right])]
lookup[left][right] = result
return lookup[left][right]
230
as-far-from-land-as-possible.py
# Given an N x N grid containing only values 0 and 1, where 0 represents
# water and 1 represents land, find a water cell such that its distance to the
# nearest land cell is maximized and return the distance.
#
# The distance used in this problem is the Manhattan distance: the distance
# between two cells (x0, y0) and (x1, y1) is |x0 - x1| + |y0 - y1|.
#
# If no land or water exists in the grid, return -1.
#
#
#
# Example 1:
#
#
#
# Input: [[1,0,1],[0,0,0],[1,0,1]]
# Output: 2
# Explanation:
# The cell (1, 1) is as far as possible from all the land with distance 2.
#
#
# Example 2:
#
#
#
# Input: [[1,0,0],[0,0,0],[0,0,0]]
# Output: 4
# Explanation:
# The cell (2, 2) is as far as possible from all the land with distance 4.
#
#
#
#
# Note:
#
#
# 1 <= grid.length == grid[0].length <= 100
# grid[i][j] is 0 or 1# Time: O(m * n)
# Space: O(m * n)
import collections
class Solution(object):
def maxDistance(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
q = collections.deque([(i, j) for i in xrange(len(grid))
for j in xrange(len(grid[0])) if grid[i][j] == 1])
if len(q) == len(grid)*len(grid[0]):
return -1
level = -1
while q:
next_q = collections.deque()
while q:
231
x, y = q.popleft()
for dx, dy in directions:
nx, ny = x+dx, y+dy
if not (0 <= nx < len(grid) and
0 <= ny < len(grid[0]) and
grid[nx][ny] == 0):
continue
next_q.append((nx, ny))
grid[nx][ny] = 1
q = next_q
level += 1
return level
232
broken-calculator.py
# On a broken calculator that has a number showing on its display, we can
# perform two operations:
#
#
# Double: Multiply the number on the display by 2, or;
# Decrement: Subtract 1 from the number on the display.
#
#
# Initially, the calculator is displaying the number X.
#
# Return the minimum number of operations needed to display the number Y.
#
#
#
# Example 1:
#
# Input: X = 2, Y = 3
# Output: 2
# Explanation: Use double operation and then decrement operation {2 -> 4 -> 3}.
#
#
# Example 2:
#
# Input: X = 5, Y = 8
# Output: 2
# Explanation: Use decrement and then double {5 -> 4 -> 8}.
#
#
# Example 3:
#
# Input: X = 3, Y = 10
# Output: 3
# Explanation: Use double, decrement and double {3 -> 6 -> 5 -> 10}.
#
#
# Example 4:
#
# Input: X = 1024, Y = 1
# Output: 1023
# Explanation: Use decrement operations 1023 times.
#
#
#
#
# Note:
#
#
# 1 <= X <= 10^9
# 1 <= Y <= 10^9# Time: O(logn)
# Space: O(1)
class Solution(object):
def brokenCalc(self, X, Y):
"""
:type X: int
:type Y: int
:rtype: int
"""
233
result = 0
while X < Y:
if Y%2:
Y += 1
else:
Y /= 2
result += 1
return result + X-Y
234
construct-binary-tree-from-preorder-and-inorder-traversal.py
# Given preorder and inorder traversal of a tree, construct the binary tree.
#
# Note:
#
# You may assume that duplicates do not exist in the tree.
#
# For example, given
#
# preorder = [3,9,20,15,7]
# inorder = [9,3,15,20,7]
#
# Return the following binary tree:
#
# 3
# / \
# 9 20
# / \
# 15 7# Time: O(n)
# Space: O(n)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
# @param preorder, a list of integers
# @param inorder, a list of integers
# @return a tree node
def buildTree(self, preorder, inorder):
lookup = {}
for i, num in enumerate(inorder):
lookup[num] = i
return self.buildTreeRecu(lookup, preorder, inorder, 0, 0, len(inorder))
# time: O(n)
# space: O(n)
class Solution2(object):
def buildTree(self, preorder, inorder):
"""
:type preorder: List[int]
:type inorder: List[int]
:rtype: TreeNode
"""
preorder_iterator = iter(preorder)
inorder_lookup = {n: i for i, n in enumerate(inorder)}
235
def helper(start, end):
if start > end:
return None
root_val = next(preorder_iterator)
root = TreeNode(root_val)
idx = inorder_lookup[root_val]
root.left = helper(start, idx-1)
root.right = helper(idx+1, end)
return root
236
longest-palindromic-substring.py
# Given a string s, find the longest palindromic substring in s. You may assume
# that the maximum length of s is 1000.
#
# Example 1:
#
# Input: "babad"
# Output: "bab"
# Note: "aba" is also a valid answer.
#
#
# Example 2:
#
# Input: "cbbd"
# Output: "bb"# Time: O(n)
# Space: O(n)
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
def preProcess(s):
if not s:
return ['^', '$']
T = ['^']
for c in s:
T += ['#', c]
T += ['#', '$']
return T
T = preProcess(s)
P = [0] * len(T)
center, right = 0, 0
for i in xrange(1, len(T) - 1):
i_mirror = 2 * center - i
if right > i:
P[i] = min(right - i, P[i_mirror])
else:
P[i] = 0
max_i = 0
for i in xrange(1, len(T) - 1):
if P[i] > P[max_i]:
max_i = i
start = (max_i - 1 - P[max_i]) / 2
return s[start : start + P[max_i]]
237
replace-words.py
# In English, we have a concept called root, which can be followed by some other
# words to form another longer word - let's call this word successor. For example,
# when the root "an" is followed by the successor word "other", we can form a new
# word "another".
#
# Given a dictionary consisting of many roots and a sentence consisting of words
# spearted by spaces. You need to replace all the successors in the sentence with
# the root forming it. If a successor can be replaced by more than one
# root, replace it with the root with the shortest length.
#
# Return the sentence after the replacement.
#
#
# Example 1:
# Input: dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by
# the battery"
# Output: "the cat was rat by the bat"
# Example 2:
# Input: dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
# Output: "a a b c"
# Example 3:
# Input: dictionary = ["a", "aa", "aaa", "aaaa"], sentence = "a aa a aaaa aaa
# aaa aaa aaaaaa bbb baba ababa"
# Output: "a a a a a a a a bbb baba a"
# Example 4:
# Input: dictionary = ["catt","cat","bat","rat"], sentence = "the cattle was
# rattled by the battery"
# Output: "the cat was rat by the bat"
# Example 5:
# Input: dictionary = ["ac","ab"], sentence = "it is abnormal that this solution
# is accepted"
# Output: "it is ab that this solution is ac"
#
#
# Constraints:
#
#
# 1 <= dictionary.length <= 1000
# 1 <= dictionary[i].length <= 100
# dictionary[i] consists of only lower-case letters.
# 1 <= sentence.length <= 10^6
# sentence consists of only lower-case letters ans spaces.
# The number of words in sentence is in the range [1, 1000]
# The length of each word in sentence is in the range [1, 1000]
# Each two words in sentence will be separted by exactly one space.
# sentence doesn't have leading or trailing spaces.# Time: O(n)
# Space: O(t), t is the number of nodes in trie
import collections
class Solution(object):
def replaceWords(self, dictionary, sentence):
"""
:type dictionary: List[str]
:type sentence: str
:rtype: str
"""
238
_trie = lambda: collections.defaultdict(_trie)
trie = _trie()
for word in dictionary:
reduce(dict.__getitem__, word, trie).setdefault("_end")
def replace(word):
curr = trie
for i, c in enumerate(word):
if c not in curr:
break
curr = curr[c]
if "_end" in curr:
return word[:i+1]
return word
239
k-concatenation-maximum-sum.py
# Given an integer array arr and an integer k, modify the array by repeating it
# k times.
#
# For example, if arr = [1, 2] and k = 3 then the modified array will be [1, 2,
# 1, 2, 1, 2].
#
# Return the maximum sub-array sum in the modified array. Note that the length
# of the sub-array can be 0 and its sum in that case is 0.
#
# As the answer can be very large, return the answer modulo 10^9 + 7.
#
#
# Example 1:
#
# Input: arr = [1,2], k = 3
# Output: 9
#
#
# Example 2:
#
# Input: arr = [1,-2,1], k = 5
# Output: 2
#
#
# Example 3:
#
# Input: arr = [-1,-2], k = 7
# Output: 0
#
#
#
# Constraints:
#
#
# 1 <= arr.length <= 10^5
# 1 <= k <= 10^5
# -10^4 <= arr[i] <= 10^4# Time: O(n)
# Space: O(1)
class Solution(object):
def kConcatenationMaxSum(self, arr, k):
"""
:type arr: List[int]
:type k: int
:rtype: int
"""
def max_sub_k_array(arr, k):
result, curr = float("-inf"), float("-inf")
for _ in xrange(k):
for x in arr:
curr = max(curr+x, x)
result = max(result, curr)
return result
MOD = 10**9+7
if k == 1:
return max(max_sub_k_array(arr, 1), 0) % MOD
return (max(max_sub_k_array(arr, 2), 0) + (k-2)*max(sum(arr), 0)) % MOD
240
ones-and-zeroes.py
# Given an array, strs, with strings consisting of only 0s and 1s. Also two
# integers m and n.
#
# Now your task is to find the maximum number of strings that you can form with
# given m 0s and n 1s. Each 0 and 1 can be used at most once.
#
#
# Example 1:
#
# Input: strs = ["10","0001","111001","1","0"], m = 5, n = 3
# Output: 4
# Explanation: This are totally 4 strings can be formed by the using of 5 0s and
# 3 1s, which are "10","0001","1","0".
#
#
# Example 2:
#
# Input: strs = ["10","0","1"], m = 1, n = 1
# Output: 2
# Explanation: You could form "10", but then you'd have nothing left. Better
# form "0" and "1".
#
#
#
# Constraints:
#
#
# 1 <= strs.length <= 600
# 1 <= strs[i].length <= 100
# strs[i] consists only of digits '0' and '1'.
# 1 <= m, n <= 100# Time: O(s * m * n), s is the size of the array.
# Space: O(m * n)
class Solution(object):
def findMaxForm(self, strs, m, n):
"""
:type strs: List[str]
:type m: int
:type n: int
:rtype: int
"""
dp = [[0 for _ in xrange(n+1)] for _ in xrange(m+1)]
for s in strs:
zero_count, one_count = 0, 0
for c in s:
if c == '0':
zero_count += 1
elif c == '1':
one_count += 1
241
validate-binary-search-tree.py
# Given a binary tree, determine if it is a valid binary search tree (BST).
#
# Assume a BST is defined as follows:
#
#
# The left subtree of a node contains only nodes with keys less than the
# node's key.
# The right subtree of a node contains only nodes with keys greater than
# the node's key.
# Both the left and right subtrees must also be binary search trees.
#
#
#
#
# Example 1:
#
# 2
# / \
# 1 3
#
# Input: [2,1,3]
# Output: true
#
#
# Example 2:
#
# 5
# / \
# 1 4
# / \
# 3 6
#
# Input: [5,1,4,null,null,3,6]
# Output: false
# Explanation: The root node's value is 5 but its right child's value is 4.# Time: O(n)
# Space: O(1)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
242
node = node.right
if node.right is None:
node.right = cur
cur = cur.left
else:
if prev and prev.val >= cur.val:
return False
node.right = None
prev = cur
cur = cur.right
return True
# Time: O(n)
# Space: O(h)
class Solution2(object):
# @param root, a tree node
# @return a boolean
def isValidBST(self, root):
return self.isValidBSTRecu(root, float("-inf"), float("inf"))
243
decoded-string-at-index.py
# An encoded string S is given. To find and write the decoded string to a tape,
# the encoded string is read one character at a time and the following steps are
# taken:
#
#
# If the character read is a letter, that letter is written onto the tape.
# If the character read is a digit (say d), the entire current tape is
# repeatedly written d-1 more times in total.
#
#
# Now for some encoded string S, and an index K, find and return the K-th letter
# (1 indexed) in the decoded string.
#
#
#
#
# Example 1:
#
# Input: S = "leet2code3", K = 10
# Output: "o"
# Explanation:
# The decoded string is "leetleetcodeleetleetcodeleetleetcode".
# The 10th letter in the string is "o".
#
#
#
# Example 2:
#
# Input: S = "ha22", K = 5
# Output: "h"
# Explanation:
# The decoded string is "hahahaha". The 5th letter is "h".
#
#
#
# Example 3:
#
# Input: S = "a2345678999999999999999", K = 1
# Output: "a"
# Explanation:
# The decoded string is "a" repeated 8301530446056247680 times. The 1st letter
# is "a".
#
#
#
#
#
#
# Constraints:
#
#
# 2 <= S.length <= 100
# S will only contain lowercase letters and digits 2 through 9.
# S starts with a letter.
# 1 <= K <= 10^9
# It's guaranteed that K is less than or equal to the length of the
# decoded string.
# The decoded string is guaranteed to have less than 2^63 letters.# Time: O(n)
244
# Space: O(1)
class Solution(object):
def decodeAtIndex(self, S, K):
"""
:type S: str
:type K: int
:rtype: str
"""
i = 0
for c in S:
if c.isdigit():
i *= int(c)
else:
i += 1
for c in reversed(S):
K %= i
if K == 0 and c.isalpha():
return c
if c.isdigit():
i /= int(c)
else:
i -= 1
245
rotate-list.py
# Given a linked list, rotate the list to the right by k places, where k is non-
# negative.
#
# Example 1:
#
# Input: 1->2->3->4->5->NULL, k = 2
# Output: 4->5->1->2->3->NULL
# Explanation:
# rotate 1 steps to the right: 5->1->2->3->4->NULL
# rotate 2 steps to the right: 4->5->1->2->3->NULL
#
#
# Example 2:
#
# Input: 0->1->2->NULL, k = 4
# Output: 2->0->1->NULL
# Explanation:
# rotate 1 steps to the right: 2->0->1->NULL
# rotate 2 steps to the right: 1->2->0->NULL
# rotate 3 steps to the right: 0->1->2->NULL
# rotate 4 steps to the right: 2->0->1->NULL# Time: O(n)
# Space: O(1)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{} -> {}".format(self.val, repr(self.next))
class Solution(object):
def rotateRight(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
if not head or not head.next:
return head
n, cur = 1, head
while cur.next:
cur = cur.next
n += 1
cur.next = head
return cur
246
minimum-path-sum.py
# Given a m x n grid filled with non-negative numbers, find a path from top left
# to bottom right which minimizes the sum of all numbers along its path.
#
# Note: You can only move either down or right at any point in time.
#
# Example:
#
# Input:
# [
# [1,3,1],
# [1,5,1],
# [4,2,1]
# ]
# Output: 7
# Explanation: Because the path 1→3→1→1→1 minimizes the sum.# Time: O(m * n)
# Space: O(m + n)
class Solution(object):
# @param grid, a list of lists of integers
# @return an integer
def minPathSum(self, grid):
sum = list(grid[0])
for j in xrange(1, len(grid[0])):
sum[j] = sum[j - 1] + grid[0][j]
return sum[-1]
247
spiral-matrix-ii.py
# Given a positive integer n, generate a square matrix filled with elements from
# 1 to n2 in spiral order.
#
# Example:
#
# Input: 3
# Output:
# [
# [ 1, 2, 3 ],
# [ 8, 9, 4 ],
# [ 7, 6, 5 ]
# ]# Time: O(n^2)
# Space: O(1)
class Solution(object):
# @return a list of lists of integer
def generateMatrix(self, n):
matrix = [[0 for _ in xrange(n)] for _ in xrange(n)]
return matrix
248
palindromic-substrings.py
# Given a string, your task is to count how many palindromic substrings in this
# string.
#
# The substrings with different start indexes or end indexes are counted as
# different substrings even they consist of same characters.
#
# Example 1:
#
# Input: "abc"
# Output: 3
# Explanation: Three palindromic strings: "a", "b", "c".
#
#
#
#
# Example 2:
#
# Input: "aaa"
# Output: 6
# Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".
#
#
#
#
# Note:
#
#
# The input string length won't exceed 1000.# Time: O(n)
# Space: O(n)
class Solution(object):
def countSubstrings(self, s):
"""
:type s: str
:rtype: int
"""
def manacher(s):
s = '^#' + '#'.join(s) + '#$'
P = [0] * len(s)
C, R = 0, 0
for i in xrange(1, len(s) - 1):
i_mirror = 2*C-i
if R > i:
P[i] = min(R-i, P[i_mirror])
while s[i+1+P[i]] == s[i-1-P[i]]:
P[i] += 1
if i+P[i] > R:
C, R = i, i+P[i]
return P
return sum((max_len+1)//2 for max_len in manacher(s))
249
numbers-with-same-consecutive-differences.py
# Example 2:
#
# Input: N = 2, K = 1
# Output: [10,12,21,23,32,34,43,45,54,56,65,67,76,78,87,89,98]# Time: O(2^n)
# Space: O(2^n)
class Solution(object):
def numsSameConsecDiff(self, N, K):
"""
:type N: int
:type K: int
:rtype: List[int]
"""
curr = range(10)
for i in xrange(N-1):
curr = [x*10 + y for x in curr for y in set([x%10 + K, x%10 - K])
if x and 0 <= y < 10]
return curr
250
longest-well-performing-interval.py
# We are given hours, a list of the number of hours worked per day for a given
# employee.
#
# A day is considered to be a tiring day if and only if the number of hours
# worked is (strictly) greater than 8.
#
# A well-performing interval is an interval of days for which the number of
# tiring days is strictly larger than the number of non-tiring days.
#
# Return the length of the longest well-performing interval.
#
#
# Example 1:
#
# Input: hours = [9,9,6,0,6,6,9]
# Output: 3
# Explanation: The longest well-performing interval is [9,9,6].
#
#
#
# Constraints:
#
#
# 1 <= hours.length <= 10000
# 0 <= hours[i] <= 16# Time: O(n)
# Space: O(n)
class Solution(object):
def longestWPI(self, hours):
"""
:type hours: List[int]
:rtype: int
"""
result, accu = 0, 0
lookup = {}
for i, h in enumerate(hours):
accu = accu+1 if h > 8 else accu-1
if accu > 0:
result = i+1
elif accu-1 in lookup:
# lookup[accu-1] is the leftmost idx with smaller accu,
# because for i from 1 to some positive k,
# lookup[accu-i] is a strickly increasing sequence
result = max(result, i-lookup[accu-1])
lookup.setdefault(accu, i)
return result
251
add-two-numbers-ii.py
# You are given two non-empty linked lists representing two non-negative
# integers. The most significant digit comes first and each of their nodes contain
# a single digit. Add the two numbers and return it as a linked list.
#
# You may assume the two numbers do not contain any leading zero, except the
# number 0 itself.
#
# Follow up:
#
# What if you cannot modify the input lists? In other words, reversing the lists
# is not allowed.
#
#
#
# Example:
# Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
# Output: 7 -> 8 -> 0 -> 7# Time: O(m + n)
# Space: O(m + n)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
stk1, stk2 = [], []
while l1:
stk1.append(l1.val)
l1 = l1.next
while l2:
stk2.append(l2.val)
l2 = l2.next
return head
252
minimum-area-rectangle-ii.py
# Example 4:
#
#
#
# Input: [[3,1],[1,1],[0,1],[2,1],[3,3],[3,2],[0,2],[2,3]]
# Output: 2.00000
# Explanation: The minimum area rectangle occurs at [2,1],[2,3],[3,3],[3,1],
# with an area of 2.# Time: O(n^2) ~ O(n^3)
# Space: O(n^2)
import collections
import itertools
class Solution(object):
def minAreaFreeRect(self, points):
"""
:type points: List[List[int]]
:rtype: float
"""
points.sort()
points = [complex(*z) for z in points]
lookup = collections.defaultdict(list)
for P, Q in itertools.combinations(points, 2):
lookup[P-Q].append((P+Q) / 2)
result = float("inf")
for A, candidates in lookup.iteritems():
for P, Q in itertools.combinations(candidates, 2):
if A.real * (P-Q).real + A.imag * (P-Q).imag == 0.0:
result = min(result, abs(A) * abs(P-Q))
return result if result < float("inf") else 0.0
253
clumsy-factorial.py
# Normally, the factorial of a positive integer n is the product of all positive
# integers less than or equal to n. For example, factorial(10) = 10 * 9 * 8 * 7 *
# 6 * 5 * 4 * 3 * 2 * 1.
#
# We instead make a clumsy factorial: using the integers in decreasing order,
# we swap out the multiply operations for a fixed rotation of operations: multiply
# (*), divide (/), add (+) and subtract (-) in this order.
#
# For example, clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1. 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.
#
# Additionally, the division that we use is floor division such that 10 * 9 /
# 8 equals 11. This guarantees the result is an integer.
#
# Implement the clumsy function as defined above: given an integer N, it returns
# the clumsy factorial of N.
#
#
#
# Example 1:
#
# Input: 4
# Output: 7
# Explanation: 7 = 4 * 3 / 2 + 1
#
#
# Example 2:
#
# Input: 10
# Output: 12
# Explanation: 12 = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1
#
#
#
#
# Note:
#
#
# 1 <= N <= 10000
# -2^31 <= answer <= 2^31 - 1 (The answer is guaranteed to fit within a
# 32-bit integer.)# Time: O(1)
# Space: O(1)
# observation:
# i*(i-1)/(i-2) = i+1+2/(i-2)
# if i = 3 => i*(i-1)/(i-2) = i + 3
# if i = 4 => i*(i-1)/(i-2) = i + 2
# if i >= 5 => i*(i-1)/(i-2) = i + 1
#
# clumsy(N):
# if N = 1 => N
# if N = 2 => N
# if N = 3 => N + 3
# if N = 4 => N + 2 + 1 = N + 3
# if N > 4 and N % 4 == 1 => N + 1 + (... = 0) + 2 - 1 = N + 2
254
# if N > 4 and N % 4 == 2 => N + 1 + (... = 0) + 3 - 2 * 1 = N + 2
# if N > 4 and N % 4 == 3 => N + 1 + (... = 0) + 4 - 3 * 2 / 1 = N - 1
# if N > 4 and N % 4 == 0 => N + 1 + (... = 0) + 5 - (4*3/2) + 1 = N + 1
class Solution(object):
def clumsy(self, N):
"""
:type N: int
:rtype: int
"""
if N <= 2:
return N
if N <= 4:
return N+3
if N % 4 == 0:
return N+1
elif N % 4 <= 2:
return N+2
return N-1
255
next-greater-element-iii.py
# Given a positive 32-bit integer n, you need to find the smallest 32-bit
# integer which has exactly the same digits existing in the integer n and is
# greater in value than n. If no such positive 32-bit integer exists, you need to
# return -1.
#
# Example 1:
#
# Input: 12
# Output: 21
#
#
#
#
# Example 2:
#
# Input: 21
# Output: -1# Time: O(logn) = O(1)
# Space: O(logn) = O(1)
class Solution(object):
def nextGreaterElement(self, n):
"""
:type n: int
:rtype: int
"""
digits = map(int, list(str(n)))
k, l = -1, 0
for i in xrange(len(digits) - 1):
if digits[i] < digits[i + 1]:
k = i
if k == -1:
digits.reverse()
return -1
256
permutations.py
# Given a collection of distinct integers, return all possible permutations.
#
# Example:
#
# Input: [1,2,3]
# Output:
# [
# [1,2,3],
# [1,3,2],
# [2,1,3],
# [2,3,1],
# [3,1,2],
# [3,2,1]
# ]# Time: O(n * n!)
# Space: O(n)
class Solution(object):
# @param num, a list of integer
# @return a list of lists of integers
def permute(self, num):
result = []
used = [False] * len(num)
self.permuteRecu(result, used, [], num)
return result
for i in xrange(len(nums)):
# e.g., [1, 2, 3]: 3! = 6 cases
# idx -> nums, path
# 0 -> [2, 3], [1] -> 0: [3], [1, 2] -> [], [1, 2, 3]
257
# -> 1: [2], [1, 3] -> [], [1, 3, 2]
#
# 1 -> [1, 3], [2] -> 0: [3], [2, 1] -> [], [2, 1, 3]
# -> 1: [1], [2, 3] -> [], [2, 3, 1]
#
# 2 -> [1, 2], [3] -> 0: [2], [3, 1] -> [], [3, 1, 2]
# -> 1: [1], [3, 2] -> [], [3, 2, 1]
self.dfs(nums[:i] + nums[i+1:], path + [nums[i]], res)
258
number-of-longest-increasing-subsequence.py
# Given an unsorted array of integers, find the number of longest increasing
# subsequence.
#
#
# Example 1:
#
# Input: [1,3,5,4,7]
# Output: 2
# Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1,
# 3, 5, 7].
#
#
#
# Example 2:
#
# Input: [2,2,2,2,2]
# Output: 5
# Explanation: The length of longest continuous increasing subsequence is 1, and
# there are 5 subsequences' length is 1, so output 5.
#
#
#
# Note:
# Length of the given array will be not exceed 2000 and the answer is guaranteed
# to be fit in 32-bit signed int.# Time: O(n^2)
# Space: O(n)
class Solution(object):
def findNumberOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
result, max_len = 0, 0
dp = [[1, 1] for _ in xrange(len(nums))] # {length, number} pair
for i in xrange(len(nums)):
for j in xrange(i):
if nums[i] > nums[j]:
if dp[i][0] == dp[j][0]+1:
dp[i][1] += dp[j][1]
elif dp[i][0] < dp[j][0]+1:
dp[i] = [dp[j][0]+1, dp[j][1]]
if max_len == dp[i][0]:
result += dp[i][1]
elif max_len < dp[i][0]:
max_len = dp[i][0]
result = dp[i][1]
return result
259
shortest-bridge.py
# In a given 2D binary array A, there are two islands. (An island is a
# 4-directionally connected group of 1s not connected to any other 1s.)
#
# Now, we may change 0s to 1s so as to connect the two islands together to form
# 1 island.
#
# Return the smallest number of 0s that must be flipped. (It is guaranteed that
# the answer is at least 1.)
#
#
# Example 1:
# Input: A = [[0,1],[1,0]]
# Output: 1
# Example 2:
# Input: A = [[0,1,0],[0,0,0],[0,0,1]]
# Output: 2
# Example 3:
# Input: A = [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
# Output: 1
#
#
# Constraints:
#
#
# 2 <= A.length == A[0].length <= 100
# A[i][j] == 0 or A[i][j] == 1# Time: O(n^2)
# Space: O(n^2)
import collections
class Solution(object):
def shortestBridge(self, A):
"""
:type A: List[List[int]]
:rtype: int
"""
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
def get_islands(A):
islands = []
done = set()
for r, row in enumerate(A):
for c, val in enumerate(row):
if val == 0 or (r, c) in done:
continue
s = [(r, c)]
lookup = set(s)
while s:
node = s.pop()
for d in directions:
nei = node[0]+d[0], node[1]+d[1]
if not (0 <= nei[0] < len(A) and 0 <= nei[1] < len(A[0])) or \
nei in lookup or A[nei[0]][nei[1]] == 0:
continue
s.append(nei)
lookup.add(nei)
done |= lookup
260
islands.append(lookup)
if len(islands) == 2:
break
return islands
261
complex-number-multiplication.py
# Given two strings representing two complex numbers.
#
#
# You need to return a string representing their multiplication. Note i2 = -1
# according to the definition.
#
#
# Example 1:
#
# Input: "1+1i", "1+1i"
# Output: "0+2i"
# Explanation: (1 + i) * (1 + i) = 1 + i2 + 2 * i = 2i, and you need convert it
# to the form of 0+2i.
#
#
#
# Example 2:
#
# Input: "1+-1i", "1+-1i"
# Output: "0+-2i"
# Explanation: (1 - i) * (1 - i) = 1 + i2 - 2 * i = -2i, and you need convert it
# to the form of 0+-2i.
#
#
#
# Note:
#
# The input strings will not have extra blank.
# The input strings will be given in the form of a+bi, where the integer a and b
# will both belong to the range of [-100, 100]. And the output should be also in
# this form.# Time: O(1)
# Space: O(1)
class Solution(object):
def complexNumberMultiply(self, a, b):
"""
:type a: str
:type b: str
:rtype: str
"""
ra, ia = map(int, a[:-1].split('+'))
rb, ib = map(int, b[:-1].split('+'))
return '%d+%di' % (ra * rb - ia * ib, ra * ib + ia * rb)
262
copy-list-with-random-pointer.py
# A linked list is given such that each node contains an additional random
# pointer which could point to any node in the list or null.
#
# Return a deep copy of the list.
#
# The Linked List is represented in the input/output as a list of n nodes. Each
# node is represented as a pair of [val, random_index] where:
#
#
# val: an integer representing Node.val
# random_index: the index of the node (range from 0 to n-1) where random
# pointer points to, or null if it does not point to any node.
#
#
#
# Example 1:
#
# Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
# Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]
#
#
# Example 2:
#
# Input: head = [[1,1],[2,1]]
# Output: [[1,1],[2,1]]
#
#
# Example 3:
#
#
#
# Input: head = [[3,null],[3,0],[3,null]]
# Output: [[3,null],[3,0],[3,null]]
#
#
# Example 4:
#
# Input: head = []
# Output: []
# Explanation: Given linked list is empty (null pointer), so return null.
#
#
#
# Constraints:
#
#
# -10000 <= Node.val <= 10000
# Node.random is null or pointing to a node in the linked list.
# Number of Nodes will not exceed 1000.# Time: O(n)
# Space: O(1)
class RandomListNode(object):
def __init__(self, x):
self.label = x
self.next = None
self.random = None
class Solution(object):
263
# @param head, a RandomListNode
# @return a RandomListNode
def copyRandomList(self, head):
# copy and combine copied list with original list
current = head
while current:
copied = RandomListNode(current.label)
copied.next = current.next
current.next = copied
current = copied.next
# Time: O(n)
# Space: O(n)
class Solution2(object):
# @param head, a RandomListNode
# @return a RandomListNode
def copyRandomList(self, head):
dummy = RandomListNode(0)
current, prev, copies = head, dummy, {}
while current:
copied = RandomListNode(current.label)
copies[current] = copied
prev.next = copied
prev, current = prev.next, current.next
current = head
while current:
if current.random:
copies[current].random = copies[current.random]
current = current.next
return dummy.next
# time: O(n)
# space: O(n)
from collections import defaultdict
class Solution3(object):
def copyRandomList(self, head):
"""
:type head: RandomListNode
:rtype: RandomListNode
264
"""
clone = defaultdict(lambda: RandomListNode(0))
clone[None] = None
cur = head
while cur:
clone[cur].label = cur.label
clone[cur].next = clone[cur.next]
clone[cur].random = clone[cur.random]
cur = cur.next
return clone[head]
265
container-with-most-water.py
# Given n non-negative integers a1, a2, ..., an , where each represents a point
# at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of
# line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis
# forms a container, such that the container contains the most water.
#
# Note: You may not slant the container and n is at least 2.
#
#
#
#
#
# The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this
# case, the max area of water (blue section) the container can contain is 49.
#
#
#
# Example:
#
# Input: [1,8,6,2,5,4,8,3,7]
# Output: 49# Time: O(n)
# Space: O(1)
class Solution(object):
# @return an integer
def maxArea(self, height):
max_area, i, j = 0, 0, len(height) - 1
while i < j:
max_area = max(max_area, min(height[i], height[j]) * (j - i))
if height[i] < height[j]:
i += 1
else:
j -= 1
return max_area
266
find-duplicate-file-in-system.py
# Given a list of directory info including directory path, and all the files
# with contents in this directory, you need to find out all the groups of
# duplicate files in the file system in terms of their paths.
#
# A group of duplicate files consists of at least two files that have exactly
# the same content.
#
# A single directory info string in the input list has the following format:
#
# "root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ...
# fn.txt(fn_content)"
#
# It means there are n files (f1.txt, f2.txt ... fn.txt with content f1_content,
# f2_content ... fn_content, respectively) in directory root/d1/d2/.../dm. Note
# that n >= 1 and m >= 0. If m = 0, it means the directory is just the root
# directory.
#
# The output is a list of group of duplicate file paths. For each group, it
# contains all the file paths of the files that have the same content. A file path
# is a string that has the following format:
#
# "directory_path/file_name.txt"
#
# Example 1:
#
# Input:
# ["root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d
# 4.txt(efgh)", "root 4.txt(efgh)"]
# Output:
#
# [["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]]
#
#
#
#
# Note:
#
#
# No order is required for the final output.
# You may assume the directory name, file name and file content only has
# letters and digits, and the length of file content is in the range of [1,50].
# The number of files given is in the range of [1,20000].
# You may assume no files or directories share the same name in the same
# directory.
# You may assume each given directory info represents a unique directory.
# Directory path and file info are separated by a single blank space.
#
#
#
# Follow-up beyond contest:
#
#
# Imagine you are given a real file system, how will you search files? DFS
# or BFS?
# If the file content is very large (GB level), how will you modify your
# solution?
# If you can only read the file by 1kb each time, how will you modify your
# solution?
267
# What is the time complexity of your modified solution? What is the most
# time-consuming part and memory consuming part of it? How to optimize?
# How to make sure the duplicated files you find are not false positive?# Time: O(n * l), l is the avera
# Space: O(n * l)
import collections
class Solution(object):
def findDuplicate(self, paths):
"""
:type paths: List[str]
:rtype: List[List[str]]
"""
files = collections.defaultdict(list)
for path in paths:
s = path.split(" ")
for i in xrange(1,len(s)):
file_name = s[0] + "/" + s[i][0:s[i].find("(")]
file_content = s[i][s[i].find("(")+1:s[i].find(")")]
files[file_content].append(file_name)
result = []
for file_content, file_names in files.iteritems():
if len(file_names)>1:
result.append(file_names)
return result
268
fraction-to-recurring-decimal.py
# Given two integers representing the numerator and denominator of a fraction,
# return the fraction in string format.
#
# If the fractional part is repeating, enclose the repeating part in
# parentheses.
#
# If multiple answers are possible, just return any of them.
#
# Example 1:
#
# Input: numerator = 1, denominator = 2
# Output: "0.5"
#
#
# Example 2:
#
# Input: numerator = 2, denominator = 1
# Output: "2"
#
# Example 3:
#
# Input: numerator = 2, denominator = 3
# Output: "0.(6)"# Time: O(logn), where logn is the length of result strings
# Space: O(1)
class Solution(object):
def fractionToDecimal(self, numerator, denominator):
"""
:type numerator: int
:type denominator: int
:rtype: str
"""
result = ""
if (numerator > 0 and denominator < 0) or (numerator < 0 and denominator > 0):
result = "-"
if dvd > 0:
result += "."
lookup = {}
while dvd and dvd not in lookup:
lookup[dvd] = len(result)
dvd *= 10
result += str(dvd / dvs)
dvd %= dvs
if dvd in lookup:
result = result[:lookup[dvd]] + "(" + result[lookup[dvd]:] + ")"
return result
269
path-with-maximum-probability.py
# You are given an undirected weighted graph of n nodes (0-indexed), represented
# by an edge list where edges[i] = [a, b] is an undirected edge connecting the
# nodes a and b with a probability of success of traversing that edge succProb[i].
#
# Given two nodes start and end, find the path with the maximum probability of
# success to go from start to end and return its success probability.
#
# If there is no path from start to end, return 0. Your answer will be accepted
# if it differs from the correct answer by at most 1e-5.
#
#
# Example 1:
#
#
#
# Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start =
# 0, end = 2
# Output: 0.25000
# Explanation: There are two paths from start to end, one having a probability
# of success = 0.2 and the other has 0.5 * 0.5 = 0.25.
#
#
# Example 2:
#
#
#
# Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start =
# 0, end = 2
# Output: 0.30000
#
#
# Example 3:
#
#
#
# Input: n = 3, edges = [[0,1]], succProb = [0.5], start = 0, end = 2
# Output: 0.00000
# Explanation: There is no path between 0 and 2.
#
#
#
# Constraints:
#
#
# 2 <= n <= 10^4
# 0 <= start, end < n
# start != end
# 0 <= a, b < n
# a != b
# 0 <= succProb.length == edges.length <= 2*10^4
# 0 <= succProb[i] <= 1
# There is at most one edge between every two nodes.# Time: O((|E| + |V|) * log|V|) = O(|E| * log|V|) by
# if we can further to use Fibonacci heap, it would be O(|E| + |V| * log|V|)
# Space: O(|E| + |V|) = O(|E|)
import collections
import itertools
import heapq
270
class Solution(object):
def maxProbability(self, n, edges, succProb, start, end):
"""
:type n: int
:type edges: List[List[int]]
:type succProb: List[float]
:type start: int
:type end: int
:rtype: float
"""
adj = collections.defaultdict(list)
for (u, v), p in itertools.izip(edges, succProb):
adj[u].append((v, p))
adj[v].append((u, p))
max_heap = [(-1.0, start)]
result, lookup = collections.defaultdict(float), set()
result[start] = 1.0
while max_heap and len(lookup) != len(adj):
curr, u = heapq.heappop(max_heap)
if u in lookup:
continue
lookup.add(u)
for v, w in adj[u]:
if v in lookup:
continue
if v in result and result[v] >= -curr*w:
continue
result[v] = -curr*w
heapq.heappush(max_heap, (-result[v], v))
return result[end]
271
house-robber-iii.py
# The thief has found himself a new place for his thievery again. There is only
# one entrance to this area, called the "root." Besides the root, each house has
# one and only one parent house. After a tour, the smart thief realized that "all
# houses in this place forms a binary tree". It will automatically contact the
# police if two directly-linked houses were broken into on the same night.
#
# Determine the maximum amount of money the thief can rob tonight without
# alerting the police.
#
# Example 1:
#
# Input: [3,2,3,null,3,null,1]
#
# 3
# / \
# 2 3
# \ \
# 3 1
#
# Output: 7
# Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
#
# Example 2:
#
# Input: [3,4,5,1,3,null,1]
#
# 3
# / \
# 4 5
# / \ \
# 1 3 1
#
# Output: 9
# Explanation: Maximum amount of money the thief can rob = 4 + 5 = 9.# Time: O(n)
# Space: O(h)
class Solution(object):
def rob(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def robHelper(root):
if not root:
return (0, 0)
left, right = robHelper(root.left), robHelper(root.right)
return (root.val + left[1] + right[1], max(left) + max(right))
return max(robHelper(root))
272
letter-tile-possibilities.py
# You have n tiles, where each tile has one letter tiles[i] printed on it.
#
# Return the number of possible non-empty sequences of letters you can make
# using the letters printed on those tiles.
#
#
# Example 1:
#
# Input: tiles = "AAB"
# Output: 8
# Explanation: The possible sequences are "A", "B", "AA", "AB", "BA", "AAB",
# "ABA", "BAA".
#
#
# Example 2:
#
# Input: tiles = "AAABBC"
# Output: 188
#
#
# Example 3:
#
# Input: tiles = "V"
# Output: 1
#
#
#
# Constraints:
#
#
# 1 <= tiles.length <= 7
# tiles consists of uppercase English letters.# Time: O(n^2)
# Space: O(n)
import collections
class Solution(object):
def numTilePossibilities(self, tiles):
"""
:type tiles: str
:rtype: int
"""
fact = [0.0]*(len(tiles)+1)
fact[0] = 1.0;
for i in xrange(1, len(tiles)+1):
fact[i] = fact[i-1]*i
count = collections.Counter(tiles)
273
coeff = [0.0]*(len(tiles)+1)
coeff[0] = 1.0
for i in count.itervalues():
new_coeff = [0.0]*(len(tiles)+1)
for j in xrange(len(coeff)):
for k in xrange(i+1):
if k+j >= len(new_coeff):
break
new_coeff[j+k] += coeff[j]*1.0/fact[k]
coeff = new_coeff
result = 0
for i in xrange(1, len(coeff)):
result += int(round(coeff[i]*fact[i]))
return result
return backtracking(collections.Counter(tiles))
274
sort-an-array.py
# Given an array of integers nums, sort the array in ascending order.
#
#
# Example 1:
# Input: nums = [5,2,3,1]
# Output: [1,2,3,5]
# Example 2:
# Input: nums = [5,1,1,2,0,0]
# Output: [0,0,1,1,2,5]
#
#
# Constraints:
#
#
# 1 <= nums.length <= 50000
# -50000 <= nums[i] <= 50000# Time: O(nlogn)
# Space: O(n)
275
for i in xrange(left, right):
if compare(nums[i], nums[right]):
nums[i], nums[new_pivot_idx] = nums[new_pivot_idx], nums[i]
new_pivot_idx += 1
right -= 1
while left <= right:
pivot_idx = random.randint(left, right)
new_pivot_idx = PartitionAroundPivot(left, right, pivot_idx, nums, compare)
if new_pivot_idx == k:
return
elif new_pivot_idx > k:
right = new_pivot_idx - 1
else: # new_pivot_idx < k.
left = new_pivot_idx + 1
276
the-dining-philosophers.py
# Five silent philosophers sit at a round table with bowls of spaghetti. Forks
# are placed between each pair of adjacent philosophers.
#
# Each philosopher must alternately think and eat. However, a philosopher can
# only eat spaghetti when they have both left and right forks. Each fork can be
# held by only one philosopher and so a philosopher can use the fork only if it is
# not being used by another philosopher. After an individual philosopher finishes
# eating, they need to put down both forks so that the forks become available to
# others. A philosopher can take the fork on their right or the one on their left
# as they become available, but cannot start eating before getting both forks.
#
# Eating is not limited by the remaining amounts of spaghetti or stomach space;
# an infinite supply and an infinite demand are assumed.
#
# Design a discipline of behaviour (a concurrent algorithm) such that no
# philosopher will starve; i.e., each can forever continue to alternate between
# eating and thinking, assuming that no philosopher can know when others may want
# to eat or think.
#
#
#
# The problem statement and the image above are taken from wikipedia.org
#
#
#
# The philosophers' ids are numbered from 0 to 4 in a clockwise order. Implement
# the function void wantsToEat(philosopher, pickLeftFork, pickRightFork, eat,
# putLeftFork, putRightFork) where:
#
#
# philosopher is the id of the philosopher who wants to eat.
# pickLeftFork and pickRightFork are functions you can call to pick the
# corresponding forks of that philosopher.
# eat is a function you can call to let the philosopher eat once he has
# picked both forks.
# putLeftFork and putRightFork are functions you can call to put down the
# corresponding forks of that philosopher.
# The philosophers are assumed to be thinking as long as they are not
# asking to eat (the function is not being called with their number).
#
#
# Five threads, each representing a philosopher, will simultaneously use one
# object of your class to simulate the process. The function may be called for the
# same philosopher more than once, even before the last call ends.
#
#
# Example 1:
#
# Input: n = 1
# Output: [[4,2,1],[4,1,1],[0,1,1],[2,2,1],[2,1,1],[2,0,3],[2,1,2],[2,2,2],[4,0,
# 3],[4,1,2],[0,2,1],[4,2,2],[3,2,1],[3,1,1],[0,0,3],[0,1,2],[0,2,2],[1,2,1],[1,1,
# 1],[3,0,3],[3,1,2],[3,2,2],[1,0,3],[1,1,2],[1,2,2]]
# Explanation:
# n is the number of times each philosopher will call the function.
# The output array describes the calls you made to the functions controlling the
# forks and the eat function, its format is:
# output[i] = [a, b, c] (three integers)
# - a is the id of a philosopher.
277
# - b specifies the fork: {1 : left, 2 : right}.
# - c specifies the operation: {1 : pick, 2 : put, 3 : eat}.
#
#
# Constraints:
#
#
# 1 <= n <= 60# Time: O(n)
# Space: O(1)
import threading
class DiningPhilosophers(object):
def __init__(self):
self._l = [threading.Lock() for _ in xrange(5)]
with self._l[first]:
with self._l[second]:
pickLeftFork()
pickRightFork()
eat()
putLeftFork()
putRightFork()
278
majority-element-ii.py
# Given an integer array of size n, find all elements that appear more than
# n/3 times.
#
# Note: The algorithm should run in linear time and in O(1) space.
#
# Example 1:
#
# Input: [3,2,3]
# Output: [3]
#
# Example 2:
#
# Input: [1,1,1,3,3,2,2,2]
# Output: [1,2]# Time: O(n)
# Space: O(1)
import collections
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
k, n, cnts = 3, len(nums), collections.defaultdict(int)
for i in nums:
cnts[i] += 1
# Detecting k items in cnts, at least one of them must have exactly
# one in it. We will discard those k items by one for each.
# This action keeps the same mojority numbers in the remaining numbers.
# Because if x / n > 1 / k is true, then (x - 1) / (n - k) > 1 / k is also true.
if len(cnts) == k:
for j in cnts.keys():
cnts[j] -= 1
if cnts[j] == 0:
del cnts[j]
return result
279
:type nums: List[int]
:rtype: List[int]
"""
return [i[0] for i in collections.Counter(nums).items() if i[1] > len(nums) / 3]
280
reordered-power-of-2.py
# Example 4:
#
# Input: 24
# Output: false
#
#
#
# Example 5:
#
# Input: 46
# Output: true
#
#
#
#
# Note:
#
#
# 1 <= N <= 10^9# Time: O((logn)^2) = O(1) due to n is a 32-bit number
# Space: O(logn) = O(1)
import collections
class Solution(object):
def reorderedPowerOf2(self, N):
"""
:type N: int
:rtype: bool
"""
count = collections.Counter(str(N))
return any(count == collections.Counter(str(1 << i))
for i in xrange(31))
281
smallest-string-starting-from-leaf.py
# Example 1:
#
#
#
# Input: [0,1,2,3,4,3,4]
# Output: "dba"
#
#
#
# Example 2:
#
#
#
# Input: [25,1,3,1,3,0,2]
# Output: "adz"
#
#
#
# Example 3:
#
#
#
# Input: [2,2,1,null,1,0,null,0]
# Output: "abc"
#
#
#
#
# Note:
#
#
# The number of nodes in the given tree will be between 1 and 8500.
# Each node in the tree will have a value between 0 and 25.# Time: O(n + l * h), l is the number of leav
# Space: O(h)
class Solution(object):
def smallestFromLeaf(self, root):
"""
:type root: TreeNode
:rtype: str
"""
def dfs(node, candidate, result):
if not node:
return
candidate.append(chr(ord('a') + node.val))
if not node.left and not node.right:
result[0] = min(result[0], "".join(reversed(candidate)))
dfs(node.left, candidate, result)
dfs(node.right, candidate, result)
282
candidate.pop()
result = ["~"]
dfs(root, [], result)
return result[0]
283
delete-nodes-and-return-forest.py
# Given the root of a binary tree, each node in the tree has a distinct value.
#
# After deleting all nodes with a value in to_delete, we are left with a forest
# (a disjoint union of trees).
#
# Return the roots of the trees in the remaining forest. You may return the
# result in any order.
#
#
# Example 1:
#
#
#
# Input: root = [1,2,3,4,5,6,7], to_delete = [3,5]
# Output: [[1,2,null,4],[6],[7]]
#
#
#
# Constraints:
#
#
# The number of nodes in the given tree is at most 1000.
# Each node has a distinct value between 1 and 1000.
# to_delete.length <= 1000
# to_delete contains distinct values between 1 and 1000.# Time: O(n)
# Space: O(h + d), d is the number of to_delete
class Solution(object):
def delNodes(self, root, to_delete):
"""
:type root: TreeNode
:type to_delete: List[int]
:rtype: List[TreeNode]
"""
def delNodesHelper(to_delete_set, root, is_root, result):
if not root:
return None
is_deleted = root.val in to_delete_set
if is_root and not is_deleted:
result.append(root)
root.left = delNodesHelper(to_delete_set, root.left, is_deleted, result)
root.right = delNodesHelper(to_delete_set, root.right, is_deleted, result)
return None if is_deleted else root
result = []
to_delete_set = set(to_delete)
delNodesHelper(to_delete_set, root, True, result)
return result
284
flip-columns-for-maximum-number-of-equal-rows.py
# Example 2:
#
# Input: [[0,1],[1,0]]
# Output: 2
# Explanation: After flipping values in the first column, both rows have equal
# values.
#
#
#
# Example 3:
#
# Input: [[0,0,0],[0,0,1],[1,1,0]]
# Output: 2
# Explanation: After flipping values in the first two columns, the last two rows
# have equal values.
#
#
#
#
# Note:
#
#
# 1 <= matrix.length <= 300
# 1 <= matrix[i].length <= 300
# All matrix[i].length's are equal
# matrix[i][j] is 0 or 1# Time: O(m * n)
# Space: O(m * n)
import collections
class Solution(object):
def maxEqualRowsAfterFlips(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: int
"""
count = collections.Counter(tuple(x^row[0] for x in row)
for row in matrix)
return max(count.itervalues())
285
advantage-shuffle.py
# Example 2:
#
# Input: A = [12,24,8,32], B = [13,25,32,11]
# Output: [24,32,8,12]
#
#
#
#
# Note:
#
#
# 1 <= A.length = B.length <= 10000
# 0 <= A[i] <= 10^9
# 0 <= B[i] <= 10^9# Time: O(nlogn)
# Space: O(n)
class Solution(object):
def advantageCount(self, A, B):
"""
:type A: List[int]
:type B: List[int]
:rtype: List[int]
"""
sortedA = sorted(A)
sortedB = sorted(B)
286
string-without-aaa-or-bbb.py
# Given two integers A and B, return any string S such that:
#
#
# S has length A + B and contains exactly A 'a' letters, and exactly B 'b'
# letters;
# The substring 'aaa' does not occur in S;
# The substring 'bbb' does not occur in S.
#
#
#
#
# Example 1:
#
# Input: A = 1, B = 2
# Output: "abb"
# Explanation: "abb", "bab" and "bba" are all correct answers.
#
#
#
# Example 2:
#
# Input: A = 4, B = 1
# Output: "aabaa"
#
#
#
#
# Note:
#
#
# 0 <= A <= 100
# 0 <= B <= 100
# It is guaranteed such an S exists for the given A and B.# Time: O(a + b)
# Space: O(1)
class Solution(object):
def strWithout3a3b(self, A, B):
"""
:type A: int
:type B: int
:rtype: str
"""
result = []
put_A = None
while A or B:
if len(result) >= 2 and result[-1] == result[-2]:
put_A = result[-1] == 'b'
else:
put_A = A >= B
if put_A:
A -= 1
result.append('a')
else:
B -= 1
result.append('b')
return "".join(result)
287
populating-next-right-pointers-in-each-node.py
# You are given a perfect binary tree where all leaves are on the same level,
# and every parent has two children. The binary tree has the following definition:
#
# struct Node {
# int val;
# Node *left;
# Node *right;
# Node *next;
# }
#
#
# Populate each next pointer to point to its next right node. If there is no
# next right node, the next pointer should be set to NULL.
#
# Initially, all next pointers are set to NULL.
#
#
#
# Follow up:
#
#
# You may only use constant extra space.
# Recursive approach is fine, you may assume implicit stack space does not
# count as extra space for this problem.
#
#
#
# Example 1:
#
#
#
# Input: root = [1,2,3,4,5,6,7]
# Output: [1,#,2,3,#,4,5,6,7,#]
# Explanation: Given the above perfect binary tree (Figure A), your function
# should populate each next pointer to point to its next right node, just like in
# Figure B. The serialized output is in level order as connected by the next
# pointers, with '#' signifying the end of each level.
#
#
#
# Constraints:
#
#
# The number of nodes in the given tree is less than 4096.
# -1000 <= node.val <= 1000# Time: O(n)
# Space: O(1)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
self.next = None
def __repr__(self):
if self is None:
return "Nil"
else:
288
return "{} -> {}".format(self.val, repr(self.next))
class Solution(object):
# @param root, a tree node
# @return nothing
def connect(self, root):
head = root
while head:
cur = head
while cur and cur.left:
cur.left.next = cur.right
if cur.next:
cur.right.next = cur.next.left
cur = cur.next
head = head.left
# Time: O(n)
# Space: O(logn)
# recusion
class Solution2(object):
# @param root, a tree node
# @return nothing
def connect(self, root):
if root is None:
return
if root.left:
root.left.next = root.right
if root.right and root.next:
root.right.next = root.next.left
self.connect(root.left)
self.connect(root.right)
289
sum-of-nodes-with-even-valued-grandparent.py
# Given a binary tree, return the sum of values of nodes with even-valued
# grandparent. (A grandparent of a node is the parent of its parent, if it
# exists.)
#
# If there are no nodes with an even-valued grandparent, return 0.
#
#
# Example 1:
#
#
#
# Input: root = [6,7,8,2,7,1,3,9,null,1,4,null,null,null,5]
# Output: 18
# Explanation: The red nodes are the nodes with even-value grandparent while the
# blue nodes are the even-value grandparents.
#
#
#
# Constraints:
#
#
# The number of nodes in the tree is between 1 and 10^4.
# The value of nodes is between 1 and 100.# Time: O(n)
# Space: O(h)
class Solution(object):
def sumEvenGrandparent(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def sumEvenGrandparentHelper(root, p, gp):
return sumEvenGrandparentHelper(root.left, root.val, p) + \
sumEvenGrandparentHelper(root.right, root.val, p) + \
(root.val if gp is not None and gp % 2 == 0 else 0) if root else 0
290
print-zero-even-odd.py
# Suppose you are given the following code:
#
# class ZeroEvenOdd {
# public ZeroEvenOdd(int n) { ... } // constructor
# public void zero(printNumber) { ... } // only output 0's
# public void even(printNumber) { ... } // only output even numbers
# public void odd(printNumber) { ... } // only output odd numbers
# }
#
#
# The same instance of ZeroEvenOdd will be passed to three different threads:
#
#
# Thread A will call zero() which should only output 0's.
# Thread B will call even() which should only ouput even numbers.
# Thread C will call odd() which should only output odd numbers.
#
#
# Each of the threads is given a printNumber method to output an integer. Modify
# the given program to output the series 010203040506... where the length of the
# series must be 2n.
#
#
#
# Example 1:
#
# Input: n = 2
# Output: "0102"
# Explanation: There are three threads being fired asynchronously. One of them
# calls zero(), the other calls even(), and the last one calls odd(). "0102" is
# the correct output.
#
#
# Example 2:
#
# Input: n = 5
# Output: "0102030405"# Time: O(n)
# Space: O(1)
import threading
class ZeroEvenOdd(object):
def __init__(self, n):
self.__n = n
self.__curr = 0
self.__cv = threading.Condition()
291
self.__curr += 1
printNumber(0)
self.__cv.notifyAll()
292
matchsticks-to-square.py
# Remember the story of Little Match Girl? By now, you know exactly what
# matchsticks the little match girl has, please find out a way you can make one
# square by using up all those matchsticks. You should not break any stick, but
# you can link them up, and each matchstick must be used exactly one time.
#
# Your input will be several matchsticks the girl has, represented with their
# stick length. Your output will either be true or false, to represent whether you
# could make one square using all the matchsticks the little match girl has.
#
# Example 1:
#
# Input: [1,1,2,2,2]
# Output: true
#
# Explanation: You can form a square with length 2, one side of the square came
# two sticks with length 1.
#
#
#
# Example 2:
#
# Input: [3,3,3,3,4]
# Output: false
#
# Explanation: You cannot find a way to form a square with all the matchsticks.
#
#
#
# Note:
#
#
# The length sum of the given matchsticks is in the range of 0 to 10^9.
# The length of the given matchstick array will not exceed 15.# Time: O(n * s * 2^n), s is the number of subse
# Space: O(n * (2^n + s))
class Solution(object):
def makesquare(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
total_len = sum(nums)
if total_len % 4:
return False
side_len = total_len / 4
fullset = (1 << len(nums)) - 1
used_subsets = []
valid_half_subsets = [0] * (1 << len(nums))
if subset_total_len == side_len:
293
for used_subset in used_subsets:
if (used_subset & subset) == 0:
valid_half_subset = used_subset | subset
valid_half_subsets[valid_half_subset] = True
if valid_half_subsets[fullset ^ valid_half_subset]:
return True
used_subsets.append(subset)
return False
294
remove-zero-sum-consecutive-nodes-from-linked-list.py
# Given the head of a linked list, we repeatedly delete consecutive sequences of
# nodes that sum to 0 until there are no such sequences.
#
# After doing so, return the head of the final linked list. You may return any
# such answer.
#
#
# (Note that in the examples below, all sequences are serializations of ListNode
# objects.)
#
# Example 1:
#
# Input: head = [1,2,-3,3,1]
# Output: [3,1]
# Note: The answer [1,2,1] would also be accepted.
#
#
# Example 2:
#
# Input: head = [1,2,3,-3,4]
# Output: [1,2,4]
#
#
# Example 3:
#
# Input: head = [1,2,3,-3,-2]
# Output: [1]
#
#
#
# Constraints:
#
#
# The given linked list will contain between 1 and 1000 nodes.
# Each node in the linked list has -1000 <= node.val <= 1000.# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def removeZeroSumSublists(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
curr = dummy = ListNode(0)
dummy.next = head
prefix = 0
lookup = collections.OrderedDict()
while curr:
295
prefix += curr.val
node = lookup.get(prefix, curr)
while prefix in lookup:
lookup.popitem()
lookup[prefix] = node
node.next = curr.next
curr = curr.next
return dummy.next
296
sort-list.py
# Sort a linked list in O(n log n) time using constant space complexity.
#
# Example 1:
#
# Input: 4->2->1->3
# Output: 1->2->3->4
#
#
# Example 2:
#
# Input: -1->5->3->4->0
# Output: -1->0->3->4->5# Time: O(nlogn)
# Space: O(logn) for stack call
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{} -> {}".format(self.val, repr(self.next))
class Solution(object):
# @param head, a ListNode
# @return a ListNode
def sortList(self, head):
if head == None or head.next == None:
return head
sorted_l1 = self.sortList(head)
sorted_l2 = self.sortList(slow)
cur = dummy
while l1 != None and l2 != None:
if l1.val <= l2.val:
cur.next, cur, l1 = l1, l1, l1.next
else:
cur.next, cur, l2 = l2, l2, l2.next
if l1 != None:
cur.next = l1
if l2 != None:
cur.next = l2
return dummy.next
297
guess-number-higher-or-lower-ii.py
# We are playing the Guess Game. The game is as follows:
#
# I pick a number from 1 to n. You have to guess which number I picked.
#
# Every time you guess wrong, I'll tell you whether the number I picked is
# higher or lower.
#
# However, when you guess a particular number x, and you guess wrong, you pay
# $x. You win the game when you guess the number I picked.
#
# Example:
#
# n = 10, I pick 8.
#
# First round: You guess 5, I tell you that it's higher. You pay $5.
# Second round: You guess 7, I tell you that it's higher. You pay $7.
# Third round: You guess 9, I tell you that it's lower. You pay $9.
#
# Game over. 8 is the number I picked.
#
# You end up paying $5 + $7 + $9 = $21.
#
#
# Given a particular n 1, find out how much money you need to have to
# guarantee a win.# Time: O(n^2)
# Space: O(n^2)
class Solution(object):
def getMoneyAmount(self, n):
"""
:type n: int
:rtype: int
"""
pay = [[0] * n for _ in xrange(n+1)]
for i in reversed(xrange(n)):
for j in xrange(i+1, n):
pay[i][j] = min(k+1 + max(pay[i][k-1], pay[k+1][j]) \
for k in xrange(i, j+1))
return pay[0][n-1]
298
flatten-nested-list-iterator.py
# Given a nested list of integers, implement an iterator to flatten it.
#
# Each element is either an integer, or a list -- whose elements may also be
# integers or other lists.
#
# Example 1:
#
#
# Input: [[1,1],2,[1,1]]
# Output: [1,1,2,1,1]
# Explanation: By calling next repeatedly until hasNext returns false,
# the order of elements returned by next should be: [1,1,2,1,1].
#
#
# Example 2:
#
# Input: [1,[4,[6]]]
# Output: [1,4,6]
# Explanation: By calling next repeatedly until hasNext returns false,
# the order of elements returned by next should be: [1,4,6].# Time: O(n), n is the number of the
# Space: O(h), h is the depth of the nested lists.
class NestedIterator(object):
def next(self):
"""
:rtype: int
"""
nestedList, i = self.__depth[-1]
self.__depth[-1][1] += 1
return nestedList[i].getInteger()
def hasNext(self):
"""
:rtype: bool
"""
while self.__depth:
nestedList, i = self.__depth[-1]
if i == len(nestedList):
self.__depth.pop()
elif nestedList[i].isInteger():
return True
else:
self.__depth[-1][1] += 1
self.__depth.append([nestedList[i].getList(), 0])
return False
299
flatten-binary-tree-to-linked-list.py
# Given a binary tree, flatten it to a linked list in-place.
#
# For example, given the following tree:
#
# 1
# / \
# 2 5
# / \ \
# 3 4 6
#
#
# The flattened tree should look like:
#
# 1
# \
# 2
# \
# 3
# \
# 4
# \
# 5
# \
# 6# Time: O(n)
# Space: O(h), h is height of binary tree
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
# @param root, a tree node
# @return nothing, do it in place
def flatten(self, root):
self.flattenRecu(root, None)
class Solution2(object):
list_head = None
# @param root, a tree node
# @return nothing, do it in place
def flatten(self, root):
if root:
self.flatten(root.right)
self.flatten(root.left)
root.right = self.list_head
root.left = None
300
self.list_head = root
301
h-index-ii.py
# Given an array of citations sorted in ascending order (each citation is a non-
# negative integer) of a researcher, write a function to compute the researcher's
# h-index.
#
# According to the definition of h-index on Wikipedia: "A scientist has
# index h if h of his/her N papers have at least h citations each, and the other N
# h papers have no more than h citations each."
#
# Example:
#
# Input: citations = [0,1,3,5,6]
# Output: 3
# Explanation: [0,1,3,5,6] means the researcher has 5 papers in total and each
# of them had
# received 0, 1, 3, 5, 6 citations respectively.
# Since the researcher has 3 papers with at least 3 citations each
# and the remaining
# two with no more than 3 citations each, her h-index is 3.
#
# Note:
#
# If there are several possible values for h, the maximum one is taken as the
# h-index.
#
# Follow up:
#
#
# This is a follow up problem to H-Index, where citations is now
# guaranteed to be sorted in ascending order.
# Could you solve it in logarithmic time complexity?# Time: O(logn)
# Space: O(1)
class Solution(object):
def hIndex(self, citations):
"""
:type citations: List[int]
:rtype: int
"""
n = len(citations)
left, right = 0, n - 1
while left <= right:
mid = (left + right) / 2
if citations[mid] >= n - mid:
right = mid - 1
else:
left = mid + 1
return n - left
302
path-sum-ii.py
# Given a binary tree and a sum, find all root-to-leaf paths where each path's
# sum equals the given sum.
#
# Note: A leaf is a node with no children.
#
# Example:
#
# Given the below binary tree and sum = 22,
#
# 5
# / \
# 4 8
# / / \
# 11 13 4
# / \ / \
# 7 2 5 1
#
#
# Return:
#
# [
# [5,4,11,2],
# [5,8,4,5]
# ]# Time: O(n)
# Space: O(h), h is height of binary tree
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
# @param root, a tree node
# @param sum, an integer
# @return a list of lists of integers
def pathSum(self, root, sum):
return self.pathSumRecu([], [], root, sum)
cur.append(root.val)
self.pathSumRecu(result, cur, root.left, sum - root.val)
self.pathSumRecu(result, cur,root.right, sum - root.val)
cur.pop()
return result
303
beautiful-arrangement.py
# Suppose you have N integers from 1 to N. We define a beautiful arrangement as
# an array that is constructed by these N numbers successfully if one of the
# following is true for the ith position (1 <= i <= N) in this array:
#
#
# The number at the ith position is divisible by i.
# i is divisible by the number at the ith position.
#
#
#
#
# Now given N, how many beautiful arrangements can you construct?
#
# Example 1:
#
# Input: 2
# Output: 2
# Explanation:
#
# The first beautiful arrangement is [1, 2]:
#
# Number at the 1st position (i=1) is 1, and 1 is divisible by i (i=1).
#
# Number at the 2nd position (i=2) is 2, and 2 is divisible by i (i=2).
#
# The second beautiful arrangement is [2, 1]:
#
# Number at the 1st position (i=1) is 2, and 2 is divisible by i (i=1).
#
# Number at the 2nd position (i=2) is 1, and i (i=2) is divisible by 1.
#
#
#
#
# Note:
#
#
# N is a positive integer and will not exceed 15.# Time: O(n!)
# Space: O(n)
class Solution(object):
def countArrangement(self, N):
"""
:type N: int
:rtype: int
"""
def countArrangementHelper(n, arr):
if n <= 0:
return 1
count = 0
for i in xrange(n):
if arr[i] % n == 0 or n % arr[i] == 0:
arr[i], arr[n-1] = arr[n-1], arr[i]
count += countArrangementHelper(n - 1, arr)
arr[i], arr[n-1] = arr[n-1], arr[i]
return count
304
return countArrangementHelper(N, range(1, N+1))
305
rotate-function.py
# Given an array of integers A and let n to be its length.
#
#
#
# Assume Bk to be an array obtained by rotating the array A k positions clock-
# wise, we define a "rotation function" F on A as follow:
#
#
#
# F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1].
#
# Calculate the maximum value of F(0), F(1), ..., F(n-1).
#
#
# Note:
#
# n is guaranteed to be less than 105.
#
#
# Example:
# A = [4, 3, 2, 6]
#
# F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25
# F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16
# F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23
# F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26
#
# So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26.# Time: O(n)
# Space: O(1)
class Solution(object):
def maxRotateFunction(self, A):
"""
:type A: List[int]
:rtype: int
"""
s = sum(A)
fi = 0
for i in xrange(len(A)):
fi += i * A[i]
result = fi
for i in xrange(1, len(A)+1):
fi += s - len(A) * A[-i]
result = max(result, fi)
return result
306
partition-array-for-maximum-sum.py
# Given an integer array A, you partition the array into (contiguous) subarrays
# of length at most K. After partitioning, each subarray has their values changed
# to become the maximum value of that subarray.
#
# Return the largest sum of the given array after partitioning.
#
#
#
# Example 1:
#
# Input: A = [1,15,7,9,2,5,10], K = 3
# Output: 84
# Explanation: A becomes [15,15,15,9,10,10,10]
#
#
#
# Note:
#
#
# 1 <= K <= A.length <= 500
# 0 <= A[i] <= 10^6# Time: O(n * k)
# Space: O(k)
class Solution(object):
def maxSumAfterPartitioning(self, A, K):
"""
:type A: List[int]
:type K: int
:rtype: int
"""
W = K+1
dp = [0]*W
for i in xrange(len(A)):
curr_max = 0
# dp[i % W] = 0; # no need in this problem
for k in xrange(1, min(K, i+1) + 1):
curr_max = max(curr_max, A[i-k+1])
dp[i % W] = max(dp[i % W], (dp[(i-k) % W] if i >= k else 0) + curr_max*k)
return dp[(len(A)-1) % W]
307
shopping-offers.py
# In LeetCode Store, there are some kinds of items to sell. Each item has a
# price.
#
#
#
# However, there are some special offers, and a special offer consists of one or
# more different kinds of items with a sale price.
#
#
#
# You are given the each item's price, a set of special offers, and the number
# we need to buy for each item.
# The job is to output the lowest price you have to pay for exactly certain
# items as given, where you could make optimal use of the special offers.
#
#
#
# Each special offer is represented in the form of an array, the last number
# represents the price you need to pay for this special offer, other numbers
# represents how many specific items you could get if you buy this offer.
#
#
# You could use any of special offers as many times as you want.
#
# Example 1:
#
# Input: [2,5], [[3,0,5],[1,2,10]], [3,2]
# Output: 14
# Explanation:
# There are two kinds of items, A and B. Their prices are $2 and $5
# respectively.
# In special offer 1, you can pay $5 for 3A and 0B
# In special offer 2, you can pay $10 for 1A and 2B.
# You need to buy 3A and 2B, so you may pay $10 for 1A and 2B (special offer
# #2), and $4 for 2A.
#
#
#
# Example 2:
#
# Input: [2,3,4], [[1,1,0,4],[2,2,1,9]], [1,2,1]
# Output: 11
# Explanation:
# The price of A is $2, and $3 for B, $4 for C.
# You may pay $4 for 1A and 1B, and $9 for 2A ,2B and 1C.
# You need to buy 1A ,2B and 1C, so you may pay $4 for 1A and 1B (special offer
# #1), and $3 for 1B, $4 for 1C.
# You cannot add more items, though only $9 for 2A ,2B and 1C.
#
#
#
# Note:
#
#
# There are at most 6 kinds of items, 100 special offers.
# For each item, you need to buy at most 6 of them.
# You are not allowed to buy more items than you want, even if that would lower
# the overall price.# Time: O(n * 2^n)
308
# Space: O(n)
class Solution(object):
def shoppingOffers(self, price, special, needs):
"""
:type price: List[int]
:type special: List[List[int]]
:type needs: List[int]
:rtype: int
"""
def shoppingOffersHelper(price, special, needs, i):
if i == len(special):
return sum(map(lambda x, y: x*y, price, needs))
result = shoppingOffersHelper(price, special, needs, i+1)
for j in xrange(len(needs)):
needs[j] -= special[i][j]
if all(need >= 0 for need in needs):
result = min(result, special[i][-1] + shoppingOffersHelper(price, special, needs, i))
for j in xrange(len(needs)):
needs[j] += special[i][j]
return result
309
construct-binary-tree-from-inorder-and-postorder-traversal.py
# Given inorder and postorder traversal of a tree, construct the binary tree.
#
# Note:
#
# You may assume that duplicates do not exist in the tree.
#
# For example, given
#
# inorder = [9,3,15,20,7]
# postorder = [9,15,7,20,3]
#
# Return the following binary tree:
#
# 3
# / \
# 9 20
# / \
# 15 7# Time: O(n)
# Space: O(n)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
# @param inorder, a list of integers
# @param postorder, a list of integers
# @return a tree node
def buildTree(self, inorder, postorder):
lookup = {}
for i, num in enumerate(inorder):
lookup[num] = i
return self.buildTreeRecu(lookup, postorder, inorder, len(postorder), 0, len(inorder))
310
teemo-attacking.py
# In LOL world, there is a hero called Teemo and his attacking can make his
# enemy Ashe be in poisoned condition. Now, given the Teemo's attacking ascending
# time series towards Ashe and the poisoning time duration per Teemo's attacking,
# you need to output the total time that Ashe is in poisoned condition.
#
# You may assume that Teemo attacks at the very beginning of a specific time
# point, and makes Ashe be in poisoned condition immediately.
#
# Example 1:
#
# Input: [1,4], 2
# Output: 4
# Explanation: At time point 1, Teemo starts attacking Ashe and makes Ashe be
# poisoned immediately.
# This poisoned status will last 2 seconds until the end of time point 2.
# And at time point 4, Teemo attacks Ashe again, and causes Ashe to be in
# poisoned status for another 2 seconds.
# So you finally need to output 4.
#
#
#
#
# Example 2:
#
# Input: [1,2], 2
# Output: 3
# Explanation: At time point 1, Teemo starts attacking Ashe and makes Ashe be
# poisoned.
# This poisoned status will last 2 seconds until the end of time point 2.
# However, at the beginning of time point 2, Teemo attacks Ashe again who is
# already in poisoned status.
# Since the poisoned status won't add up together, though the second poisoning
# attack will still work at time point 2, it will stop at the end of time point 3.
# So you finally need to output 3.
#
#
#
#
# Note:
#
#
# You may assume the length of given time series array won't exceed 10000.
# You may assume the numbers in the Teemo's attacking time series and his
# poisoning time duration per attacking are non-negative integers, which won't
# exceed 10,000,000.# Time: O(n)
# Space: O(1)
class Solution(object):
def findPoisonedDuration(self, timeSeries, duration):
"""
:type timeSeries: List[int]
:type duration: int
:rtype: int
"""
result = duration * len(timeSeries)
for i in xrange(1, len(timeSeries)):
result -= max(0, duration - (timeSeries[i] - timeSeries[i-1]))
return result
311
largest-divisible-subset.py
# Input: [1,2,3]
# Output: [1,2] (of course, [1,3] will also be ok)
#
#
#
# Example 2:
#
# Input: [1,2,4,8]
# Output: [1,2,4,8]# Time: O(n^2)
# Space: O(n)
class Solution(object):
def largestDivisibleSubset(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
if not nums:
return []
nums.sort()
dp = [1] * len(nums)
prev = [-1] * len(nums)
largest_idx = 0
for i in xrange(len(nums)):
for j in xrange(i):
if nums[i] % nums[j] == 0:
if dp[i] < dp[j] + 1:
dp[i] = dp[j] + 1
prev[i] = j
if dp[largest_idx] < dp[i]:
largest_idx = i
result = []
i = largest_idx
while i != -1:
result.append(nums[i])
i = prev[i]
return result[::-1]
312
word-subsets.py
# Example 1:
#
# Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["e","o"]
# Output: ["facebook","google","leetcode"]
#
#
#
# Example 2:
#
# Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["l","e"]
# Output: ["apple","google","leetcode"]
#
#
#
# Example 3:
#
# Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["e","oo"]
# Output: ["facebook","google"]
#
#
#
# Example 4:
#
# Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["lo","eo"]
# Output: ["google","leetcode"]
#
#
#
# Example 5:
#
# Input: A = ["amazon","apple","facebook","google","leetcode"], B =
# ["ec","oc","ceo"]
# Output: ["facebook","leetcode"]
#
#
#
#
# Note:
#
#
# 1 <= A.length, B.length <= 10000
# 1 <= A[i].length, B[i].length <= 10
# A[i] and B[i] consist only of lowercase letters.
# All words in A[i] are unique: there isn't i != j with A[i] == A[j].# Time: O(m + n)
# Space: O(1)
import collections
class Solution(object):
def wordSubsets(self, A, B):
"""
:type A: List[str]
:type B: List[str]
:rtype: List[str]
"""
count = collections.Counter()
for b in B:
313
for c, n in collections.Counter(b).items():
count[c] = max(count[c], n)
result = []
for a in A:
count = collections.Counter(a)
if all(count[c] >= count[c] for c in count):
result.append(a)
return result
314
satisfiability-of-equality-equations.py
# Example 2:
#
# Input: ["b==a","a==b"]
# Output: true
# Explanation: We could assign a = 1 and b = 1 to satisfy both equations.
#
#
#
# Example 3:
#
# Input: ["a==b","b==c","a==c"]
# Output: true
#
#
#
# Example 4:
#
# Input: ["a==b","b!=c","c==a"]
# Output: false
#
#
#
# Example 5:
#
# Input: ["c==c","b==d","x!=z"]
# Output: true
#
#
#
#
# Note:
#
#
# 1 <= equations.length <= 500
# equations[i].length == 4
# equations[i][0] and equations[i][3] are lowercase letters
# equations[i][1] is either '=' or '!'
# equations[i][2] is '='# Time: O(n)
# Space: O(1)
class UnionFind(object):
def __init__(self, n):
self.set = range(n)
class Solution(object):
315
def equationsPossible(self, equations):
"""
:type equations: List[str]
:rtype: bool
"""
union_find = UnionFind(26)
for eqn in equations:
x = ord(eqn[0]) - ord('a')
y = ord(eqn[3]) - ord('a')
if eqn[1] == '=':
union_find.union_set(x, y)
for eqn in equations:
x = ord(eqn[0]) - ord('a')
y = ord(eqn[3]) - ord('a')
if eqn[1] == '!':
if union_find.find_set(x) == union_find.find_set(y):
return False
return True
# Time: O(n)
# Space: O(1)
class Solution2(object):
def equationsPossible(self, equations):
"""
:type equations: List[str]
:rtype: bool
"""
graph = [[] for _ in xrange(26)]
color = [None]*26
c = 0
for i in xrange(26):
if color[i] is not None:
continue
c += 1
stack = [i]
while stack:
node = stack.pop()
for nei in graph[node]:
if color[nei] is not None:
continue
color[nei] = c
stack.append(nei)
316
if color[x] is not None and \
color[x] == color[y]:
return False
return True
317
unique-substrings-in-wraparound-string.py
# Consider the string s to be the infinite wraparound string of
# "abcdefghijklmnopqrstuvwxyz", so s will look like this:
# "...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....".
#
# Now we have another string p. Your job is to find out how many unique non-
# empty substrings of p are present in s. In particular, your input is the string
# p and you need to output the number of different non-empty substrings of p in
# the string s.
#
# Note: p consists of only lowercase English letters and the size of p might be
# over 10000.
#
# Example 1:
#
# Input: "a"
# Output: 1
#
# Explanation: Only the substring "a" of string "a" is in the string s.
#
#
#
# Example 2:
#
# Input: "cac"
# Output: 2
# Explanation: There are two substrings "a", "c" of string "cac" in the string
# s.
#
#
#
# Example 3:
#
# Input: "zab"
# Output: 6
# Explanation: There are six substrings "z", "a", "b", "za", "ab", "zab" of
# string "zab" in the string s.# Time: O(n)
# Space: O(1)
class Solution(object):
def findSubstringInWraproundString(self, p):
"""
:type p: str
:rtype: int
"""
letters = [0] * 26
result, length = 0, 0
for i in xrange(len(p)):
curr = ord(p[i]) - ord('a')
if i > 0 and ord(p[i-1]) != (curr-1)%26 + ord('a'):
length = 0
length += 1
if length > letters[curr]:
result += length - letters[curr]
letters[curr] = length
return result
318
exclusive-time-of-functions.py
# On a single threaded CPU, we execute some functions. Each function has a
# unique id between 0 and N-1.
#
# We store logs in timestamp order that describe when a function is entered or
# exited.
#
# Each log is a string with this format: "{function_id}:{"start" |
# "end"}:{timestamp}". For example, "0:start:3" means the function with id 0
# started at the beginning of timestamp 3. "1:end:2" means the function with id 1
# ended at the end of timestamp 2.
#
# A function's exclusive time is the number of units of time spent in this
# function. Note that this does not include any recursive calls to child
# functions.
#
# The CPU is single threaded which means that only one function is being
# executed at a given time unit.
#
# Return the exclusive time of each function, sorted by their function id.
#
#
#
# Example 1:
#
#
#
# Input:
# n = 2
# logs = ["0:start:0","1:start:2","1:end:5","0:end:6"]
# Output: [3, 4]
# Explanation:
# Function 0 starts at the beginning of time 0, then it executes 2 units of time
# and reaches the end of time 1.
# Now function 1 starts at the beginning of time 2, executes 4 units of time and
# ends at time 5.
# Function 0 is running again at the beginning of time 6, and also ends at the
# end of time 6, thus executing for 1 unit of time.
# So function 0 spends 2 + 1 = 3 units of total time executing, and function 1
# spends 4 units of total time executing.
#
#
#
#
# Note:
#
#
# 1 <= n <= 100
# Two functions won't start or end at the same time.
# Functions will always log when they exit.# Time: O(n)
# Space: O(n)
class Solution(object):
def exclusiveTime(self, n, logs):
"""
:type n: int
:type logs: List[str]
:rtype: List[int]
"""
319
result = [0] * n
stk, prev = [], 0
for log in logs:
tokens = log.split(":")
if tokens[1] == "start":
if stk:
result[stk[-1]] += int(tokens[2]) - prev
stk.append(int(tokens[0]))
prev = int(tokens[2])
else:
result[stk.pop()] += int(tokens[2]) - prev + 1
prev = int(tokens[2]) + 1
return result
320
flip-equivalent-binary-trees.py
# For a binary tree T, we can define a flip operation as follows: choose any
# node, and swap the left and right child subtrees.
#
# A binary tree X is flip equivalent to a binary tree Y if and only if we can
# make X equal to Y after some number of flip operations.
#
# Given the roots of two binary trees root1 and root2, return true if the two
# trees are flip equivelent or false otherwise.
#
#
# Example 1:
#
# Input: root1 = [1,2,3,4,5,6,null,null,null,7,8], root2 =
# [1,3,2,null,6,4,5,null,null,null,null,8,7]
# Output: true
# Explanation: We flipped at nodes with values 1, 3, and 5.
#
#
# Example 2:
#
# Input: root1 = [], root2 = []
# Output: true
#
#
# Example 3:
#
# Input: root1 = [], root2 = [1]
# Output: false
#
#
# Example 4:
#
# Input: root1 = [0,null,1], root2 = []
# Output: false
#
#
# Example 5:
#
# Input: root1 = [0,null,1], root2 = [0,1]
# Output: true
#
#
#
# Constraints:
#
#
# The number of nodes in each tree is in the range [0, 100].
# Each value in each tree will be a unique integer in the range [0, 99].# Time: O(n)
# Space: O(h)
class Solution(object):
321
def flipEquiv(self, root1, root2):
"""
:type root1: TreeNode
:type root2: TreeNode
:rtype: bool
"""
if not root1 and not root2:
return True
if not root1 or not root2 or root1.val != root2.val:
return False
322
linked-list-cycle-ii.py
# Given a linked list, return the node where the cycle begins. If there is no
# cycle, return null.
#
# To represent a cycle in the given linked list, we use an integer pos which
# represents the position (0-indexed) in the linked list where tail connects to.
# If pos is -1, then there is no cycle in the linked list.
#
# Note: Do not modify the linked list.
#
#
#
# Example 1:
#
# Input: head = [3,2,0,-4], pos = 1
# Output: tail connects to node index 1
# Explanation: There is a cycle in the linked list, where tail connects to the
# second node.
#
#
#
#
# Example 2:
#
# Input: head = [1,2], pos = 0
# Output: tail connects to node index 0
# Explanation: There is a cycle in the linked list, where tail connects to the
# first node.
#
#
#
#
# Example 3:
#
# Input: head = [1], pos = -1
# Output: no cycle
# Explanation: There is no cycle in the linked list.
#
#
#
#
#
#
# Follow-up:
#
# Can you solve it without using extra space?# Time: O(n)
# Space: O(1)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __str__(self):
if self:
return "{}".format(self.val)
else:
return None
323
class Solution(object):
# @param head, a ListNode
# @return a list node
def detectCycle(self, head):
fast, slow = head, head
while fast and fast.next:
fast, slow = fast.next.next, slow.next
if fast is slow:
fast = head
while fast is not slow:
fast, slow = fast.next, slow.next
return fast
return None
324
maximum-subarray-sum-with-one-deletion.py
# Given an array of integers, return the maximum sum for a non-empty subarray
# (contiguous elements) with at most one element deletion. In other words, you
# want to choose a subarray and optionally delete one element from it so that
# there is still at least one element left and the sum of the remaining elements
# is maximum possible.
#
# Note that the subarray needs to be non-empty after deleting one element.
#
#
# Example 1:
#
# Input: arr = [1,-2,0,3]
# Output: 4
# Explanation: Because we can choose [1, -2, 0, 3] and drop -2, thus the
# subarray [1, 0, 3] becomes the maximum value.
#
# Example 2:
#
# Input: arr = [1,-2,-2,3]
# Output: 3
# Explanation: We just choose [3] and it's the maximum sum.
#
#
# Example 3:
#
# Input: arr = [-1,-1,-1,-1]
# Output: -1
# Explanation: The final subarray needs to be non-empty. You can't choose [-1]
# and delete -1 from it, then get an empty subarray to make the sum equals to 0.
#
#
#
# Constraints:
#
#
# 1 <= arr.length <= 10^5
# -10^4 <= arr[i] <= 10^4class Solution(object):
def maximumSum(self, arr):
"""
:type arr: List[int]
:rtype: int
"""
result, prev, curr = float("-inf"), float("-inf"), float("-inf")
for x in arr:
curr = max(prev, curr+x, x)
result = max(result, curr)
prev = max(prev+x, x)
return result
325
sort-colors.py
# Given an array with n objects colored red, white or blue, sort them in-
# place so that objects of the same color are adjacent, with the colors in the
# order red, white and blue.
#
# Here, we will use the integers 0, 1, and 2 to represent the color red, white,
# and blue respectively.
#
# Note: You are not suppose to use the library's sort function for this problem.
#
# Example:
#
# Input: [2,0,2,1,1,0]
# Output: [0,0,1,1,2,2]
#
# Follow up:
#
#
# A rather straight forward solution is a two-pass algorithm using
# counting sort.
#
# First, iterate the array counting number of 0's, 1's, and 2's, then
# overwrite array with total number of 0's, then 1's and followed by 2's.
# Could you come up with a one-pass algorithm using only constant space?# Time: O(n)
# Space: O(1)
class Solution(object):
def sortColors(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
def triPartition(nums, target):
i, left, right = 0, 0, len(nums)-1
while i <= right:
if nums[i] > target:
nums[i], nums[right] = nums[right], nums[i]
right -= 1
else:
if nums[i] < target:
nums[left], nums[i] = nums[i], nums[left]
left += 1
i += 1
triPartition(nums, 1)
326
peeking-iterator.py
# Given an Iterator class interface with methods: next() and hasNext(), design
# and implement a PeekingIterator that support the peek() operation -- it
# essentially peek() at the element that will be returned by the next call to
# next().
#
# Example:
#
# Assume that the iterator is initialized to the beginning of the list: [1,2,3].
#
# Call next() gets you 1, the first element in the list.
# Now you call peek() and it returns 2, the next element. Calling next() after
# that still return 2.
# You call next() the final time and it returns 3, the last element.
# Calling hasNext() after that should return false.
#
#
# Follow up: How would you extend your design to be generic and work with all
# types, not just integer?# Time: O(1) per peek(), next(), hasNext()
# Space: O(1)
class PeekingIterator(object):
def __init__(self, iterator):
"""
Initialize your data structure here.
:type iterator: Iterator
"""
self.iterator = iterator
self.val_ = None
self.has_next_ = iterator.hasNext()
self.has_peeked_ = False
def peek(self):
"""
Returns the next element in the iteration without advancing the iterator.
:rtype: int
"""
if not self.has_peeked_:
self.has_peeked_ = True
self.val_ = self.iterator.next()
return self.val_
def next(self):
"""
:rtype: int
"""
self.val_ = self.peek()
self.has_peeked_ = False
self.has_next_ = self.iterator.hasNext()
return self.val_
def hasNext(self):
"""
:rtype: bool
"""
return self.has_next_
327
number-of-matching-subsequences.py
# Given string S and a dictionary of words words, find the number of words[i]
# that is a subsequence of S.
#
# Example :
# Input:
# S = "abcde"
# words = ["a", "bb", "acd", "ace"]
# Output: 3
# Explanation: There are three words in words that are a subsequence of S: "a",
# "acd", "ace".
#
#
# Note:
#
#
# All words in words and S will only consists of lowercase letters.
# The length of S will be in the range of [1, 50000].
# The length of words will be in the range of [1, 5000].
# The length of words[i] will be in the range of [1, 50].# Time: O(n + w), n is the size of S, w is the
# Space: O(k), k is the number of words
import collections
class Solution(object):
def numMatchingSubseq(self, S, words):
"""
:type S: str
:type words: List[str]
:rtype: int
"""
waiting = collections.defaultdict(list)
for word in words:
it = iter(word)
waiting[next(it, None)].append(it)
for c in S:
for it in waiting.pop(c, ()):
waiting[next(it, None)].append(it)
return len(waiting[None])
328
find-largest-value-in-each-tree-row.py
# Given the root of a binary tree, return an array of the largest value in each
# row of the tree (0-indexed).
#
#
#
#
# Example 1:
#
# Input: root = [1,3,2,5,3,null,9]
# Output: [1,3,9]
#
#
# Example 2:
#
# Input: root = [1,2,3]
# Output: [1,3]
#
#
# Example 3:
#
# Input: root = [1]
# Output: [1]
#
#
# Example 4:
#
# Input: root = [1,null,2]
# Output: [1,2]
#
#
# Example 5:
#
# Input: root = []
# Output: []
#
#
#
# Constraints:
#
#
# The number of the nodes in the tree will be in the range [1, 104].
# -231 <= Node.val <= 231 - 1# Time: O(n)
# Space: O(h)
class Solution(object):
def largestValues(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
def largestValuesHelper(root, depth, result):
if not root:
return
if depth == len(result):
result.append(root.val)
else:
result[depth] = max(result[depth], root.val)
largestValuesHelper(root.left, depth+1, result)
329
largestValuesHelper(root.right, depth+1, result)
result = []
largestValuesHelper(root, 0, result)
return result
# Time: O(n)
# Space: O(n)
class Solution2(object):
def largestValues(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
result = []
curr = [root]
while any(curr):
result.append(max(node.val for node in curr))
curr = [child for node in curr for child in (node.left, node.right) if child]
return result
330
contiguous-array.py
# Given a binary array, find the maximum length of a contiguous subarray with
# equal number of 0 and 1.
#
#
# Example 1:
#
# Input: [0,1]
# Output: 2
# Explanation: [0, 1] is the longest contiguous subarray with equal number of 0
# and 1.
#
#
#
# Example 2:
#
# Input: [0,1,0]
# Output: 2
# Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal
# number of 0 and 1.
#
#
#
# Note:
# The length of the given binary array will not exceed 50,000.# Time: O(n)
# Space: O(n)
class Solution(object):
def findMaxLength(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
result, count = 0, 0
lookup = {0: -1}
for i, num in enumerate(nums):
count += 1 if num == 1 else -1
if count in lookup:
result = max(result, i - lookup[count])
else:
lookup[count] = i
return result
331
pacific-atlantic-water-flow.py
# Given an m x n matrix of non-negative integers representing the height of each
# unit cell in a continent, the "Pacific ocean" touches the left and top edges of
# the matrix and the "Atlantic ocean" touches the right and bottom edges.
#
# Water can only flow in four directions (up, down, left, or right) from a cell
# to another one with height equal or lower.
#
# Find the list of grid coordinates where water can flow to both the Pacific and
# Atlantic ocean.
#
# Note:
#
#
# The order of returned grid coordinates does not matter.
# Both m and n are less than 150.
#
#
#
#
# Example:
#
# Given the following 5x5 matrix:
#
# Pacific ~ ~ ~ ~ ~
# ~ 1 2 2 3 (5) *
# ~ 3 2 3 (4) (4) *
# ~ 2 4 (5) 3 1 *
# ~ (6) (7) 1 4 5 *
# ~ (5) 1 1 2 4 *
# * * * * * Atlantic
#
# Return:
#
# [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with
# parentheses in above matrix).# Time: O(m * n)
# Space: O(m * n)
class Solution(object):
def pacificAtlantic(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[List[int]]
"""
PACIFIC, ATLANTIC = 1, 2
visited[x][y] |= prev_val
if visited[x][y] == (PACIFIC | ATLANTIC):
res.append((x, y))
332
if not matrix:
return []
res = []
m, n = len(matrix),len(matrix[0])
visited = [[0 for _ in xrange(n)] for _ in xrange(m)]
for i in xrange(m):
pacificAtlanticHelper(matrix, i, 0, float("-inf"), PACIFIC, visited, res)
pacificAtlanticHelper(matrix, i, n - 1, float("-inf"), ATLANTIC, visited, res)
for j in xrange(n):
pacificAtlanticHelper(matrix, 0, j, float("-inf"), PACIFIC, visited, res)
pacificAtlanticHelper(matrix, m - 1, j, float("-inf"), ATLANTIC, visited, res)
return res
333
minesweeper.py
# Let's play the minesweeper game (Wikipedia, online game)!
#
# You are given a 2D char matrix representing the game board. 'M' represents an
# unrevealed mine, 'E' represents an unrevealed empty square, 'B' represents a
# revealed blank square that has no adjacent (above, below, left, right, and all 4
# diagonals) mines, digit ('1' to '8') represents how many mines are adjacent to
# this revealed square, and finally 'X' represents a revealed mine.
#
# Now given the next click position (row and column indices) among all the
# unrevealed squares ('M' or 'E'), return the board after revealing this position
# according to the following rules:
#
#
# If a mine ('M') is revealed, then the game is over - change it to 'X'.
# If an empty square ('E') with no adjacent mines is revealed, then change
# it to revealed blank ('B') and all of its adjacent unrevealed squares should be
# revealed recursively.
# If an empty square ('E') with at least one adjacent mine is revealed,
# then change it to a digit ('1' to '8') representing the number of adjacent
# mines.
# Return the board when no more squares will be revealed.
#
#
#
#
# Example 1:
#
# Input:
#
# [['E', 'E', 'E', 'E', 'E'],
# ['E', 'E', 'M', 'E', 'E'],
# ['E', 'E', 'E', 'E', 'E'],
# ['E', 'E', 'E', 'E', 'E']]
#
# Click : [3,0]
#
# Output:
#
# [['B', '1', 'E', '1', 'B'],
# ['B', '1', 'M', '1', 'B'],
# ['B', '1', '1', '1', 'B'],
# ['B', 'B', 'B', 'B', 'B']]
#
# Explanation:
#
#
#
# Example 2:
#
# Input:
#
# [['B', '1', 'E', '1', 'B'],
# ['B', '1', 'M', '1', 'B'],
# ['B', '1', '1', '1', 'B'],
# ['B', 'B', 'B', 'B', 'B']]
#
# Click : [1,2]
#
334
# Output:
#
# [['B', '1', 'E', '1', 'B'],
# ['B', '1', 'X', '1', 'B'],
# ['B', '1', '1', '1', 'B'],
# ['B', 'B', 'B', 'B', 'B']]
#
# Explanation:
#
#
#
#
#
# Note:
#
#
# The range of the input matrix's height and width is [1,50].
# The click position will only be an unrevealed square ('M' or 'E'), which
# also means the input board contains at least one clickable square.
# The input board won't be a stage when game is over (some mines have been
# revealed).
# For simplicity, not mentioned rules should be ignored in this problem.
# For example, you don't need to reveal all the unrevealed mines when the game is
# over, consider any cases that you will win the game or flag any squares.# Time: O(m * n)
# Space: O(m + n)
import collections
class Solution(object):
def updateBoard(self, board, click):
"""
:type board: List[List[str]]
:type click: List[int]
:rtype: List[List[str]]
"""
q = collections.deque([click])
while q:
row, col = q.popleft()
if board[row][col] == 'M':
board[row][col] = 'X'
else:
count = 0
for i in xrange(-1, 2):
for j in xrange(-1, 2):
if i == 0 and j == 0:
continue
r, c = row + i, col + j
if not (0 <= r < len(board)) or not (0 <= c < len(board[r])):
continue
if board[r][c] == 'M' or board[r][c] == 'X':
count += 1
if count:
board[row][col] = chr(count + ord('0'))
else:
board[row][col] = 'B'
for i in xrange(-1, 2):
for j in xrange(-1, 2):
if i == 0 and j == 0:
335
continue
r, c = row + i, col + j
if not (0 <= r < len(board)) or not (0 <= c < len(board[r])):
continue
if board[r][c] == 'E':
q.append((r, c))
board[r][c] = ' '
return board
# Time: O(m * n)
# Space: O(m * n)
class Solution2(object):
def updateBoard(self, board, click):
"""
:type board: List[List[str]]
:type click: List[int]
:rtype: List[List[str]]
"""
row, col = click[0], click[1]
if board[row][col] == 'M':
board[row][col] = 'X'
else:
count = 0
for i in xrange(-1, 2):
for j in xrange(-1, 2):
if i == 0 and j == 0:
continue
r, c = row + i, col + j
if not (0 <= r < len(board)) or not (0 <= c < len(board[r])):
continue
if board[r][c] == 'M' or board[r][c] == 'X':
count += 1
if count:
board[row][col] = chr(count + ord('0'))
else:
board[row][col] = 'B'
for i in xrange(-1, 2):
for j in xrange(-1, 2):
if i == 0 and j == 0:
continue
r, c = row + i, col + j
if not (0 <= r < len(board)) or not (0 <= c < len(board[r])):
continue
if board[r][c] == 'E':
self.updateBoard(board, (r, c))
return board
336
count-numbers-with-unique-digits.py
# Given a non-negative integer n, count all numbers with unique digits, x, where
# 0 x < 10n.
#
#
# Example:
#
# Input: 2
# Output: 91
# Explanation: The answer should be the total numbers in the range of 0 x <
# 100,
# excluding 11,22,33,44,55,66,77,88,99
#
#
#
# Constraints:
#
#
# 0 <= n <= 8# Time: O(n)
# Space: O(1)
class Solution(object):
def countNumbersWithUniqueDigits(self, n):
"""
:type n: int
:rtype: int
"""
if n == 0:
return 1
count, fk = 10, 9
for k in xrange(2, n+1):
fk *= 10 - (k-1)
count += fk
return count
337
most-stones-removed-with-same-row-or-column.py
# Example 2:
#
# Input: stones = [[0,0],[0,2],[1,1],[2,0],[2,2]]
# Output: 3
#
#
#
# Example 3:
#
# Input: stones = [[0,0]]
# Output: 0
#
#
#
#
# Note:
#
#
# 1 <= stones.length <= 1000
# 0 <= stones[i][j] < 10000# Time: O(n)
# Space: O(n)
class UnionFind(object):
def __init__(self, n):
self.set = range(n)
class Solution(object):
def removeStones(self, stones):
"""
:type stones: List[List[int]]
:rtype: int
"""
MAX_ROW = 10000
union_find = UnionFind(2*MAX_ROW)
for r, c in stones:
union_find.union_set(r, c+MAX_ROW)
return len(stones) - len({union_find.find_set(r) for r, _ in stones})
338
previous-permutation-with-one-swap.py
# Given an array A of positive integers (not necessarily distinct), return the
# lexicographically largest permutation that is smaller than A, that can be made
# with one swap (A swap exchanges the positions of two numbers A[i] and A[j]). If
# it cannot be done, then return the same array.
#
#
#
# Example 1:
#
# Input: [3,2,1]
# Output: [3,1,2]
# Explanation: Swapping 2 and 1.
#
#
# Example 2:
#
# Input: [1,1,5]
# Output: [1,1,5]
# Explanation: This is already the smallest permutation.
#
#
# Example 3:
#
# Input: [1,9,4,6,7]
# Output: [1,7,4,6,9]
# Explanation: Swapping 9 and 7.
#
#
# Example 4:
#
# Input: [3,1,1,3]
# Output: [1,3,1,3]
# Explanation: Swapping 1 and 3.
#
#
#
#
# Note:
#
#
# 1 <= A.length <= 10000
# 1 <= A[i] <= 10000# Time: O(n)
# Space: O(1)
class Solution(object):
def prevPermOpt1(self, A):
"""
:type A: List[int]
:rtype: List[int]
"""
for left in reversed(xrange(len(A)-1)):
if A[left] > A[left+1]:
break
else:
return A
right = len(A)-1
while A[left] <= A[right]:
right -= 1
339
while A[right-1] == A[right]:
right -= 1
A[left], A[right] = A[right], A[left]
return A
340
spiral-matrix.py
# Given a matrix of m x n elements (m rows, n columns), return all elements of
# the matrix in spiral order.
#
# Example 1:
#
# Input:
# [
# [ 1, 2, 3 ],
# [ 4, 5, 6 ],
# [ 7, 8, 9 ]
# ]
# Output: [1,2,3,6,9,8,7,4,5]
#
#
# Example 2:
# Input:
# [
# [1, 2, 3, 4],
# [5, 6, 7, 8],
# [9,10,11,12]
# ]
# Output: [1,2,3,4,8,12,11,10,9,5,6,7]# Time: O(m * n)
# Space: O(1)
class Solution(object):
# @param matrix, a list of lists of integers
# @return a list of integers
def spiralOrder(self, matrix):
result = []
if matrix == []:
return result
return result
341
invalid-transactions.py
# A transaction is possibly invalid if:
#
#
# the amount exceeds $1000, or;
# if it occurs within (and including) 60 minutes of another transaction
# with the same name in a different city.
#
#
# Each transaction string transactions[i] consists of comma separated values
# representing the name, time (in minutes), amount, and city of the transaction.
#
# Given a list of transactions, return a list of transactions that are possibly
# invalid. You may return the answer in any order.
#
#
# Example 1:
#
# Input: transactions = ["alice,20,800,mtv","alice,50,100,beijing"]
# Output: ["alice,20,800,mtv","alice,50,100,beijing"]
# Explanation: The first transaction is invalid because the second transaction
# occurs within a difference of 60 minutes, have the same name and is in a
# different city. Similarly the second one is invalid too.
#
# Example 2:
#
# Input: transactions = ["alice,20,800,mtv","alice,50,1200,mtv"]
# Output: ["alice,50,1200,mtv"]
#
#
# Example 3:
#
# Input: transactions = ["alice,20,800,mtv","bob,50,1200,mtv"]
# Output: ["bob,50,1200,mtv"]
#
#
#
# Constraints:
#
#
# transactions.length <= 1000
# Each transactions[i] takes the form "{name},{time},{amount},{city}"
# Each {name} and {city} consist of lowercase English letters, and have
# lengths between 1 and 10.
# Each {time} consist of digits, and represent an integer between 0 and
# 1000.
# Each {amount} consist of digits, and represent an integer between 0 and
# 2000.# Time: O(nlogn)
# Space: O(n)
import collections
class Solution:
def invalidTransactions(self, transactions):
AMOUNT, MINUTES = 1000, 60
trans = map(lambda x: (x[0], int(x[1]), int(x[2]), x[3]),
(transaction.split(',') for transaction in transactions))
342
trans.sort(key=lambda t: t[1])
trans_indexes = collections.defaultdict(list)
for i, t in enumerate(trans):
trans_indexes[t[0]].append(i)
result = []
for name, indexes in trans_indexes.iteritems():
left, right = 0, 0
for i, t_index in enumerate(indexes):
t = trans[t_index]
if (t[2] > AMOUNT):
result.append("{},{},{},{}".format(*t))
continue
while left+1 < len(indexes) and trans[indexes[left]][1] < t[1]-MINUTES:
left += 1
while right+1 < len(indexes) and trans[indexes[right+1]][1] <= t[1]+MINUTES:
right += 1
for i in xrange(left, right+1):
if trans[indexes[i]][3] != t[3]:
result.append("{},{},{},{}".format(*t))
break
return result
343
counting-bits.py
# Given a non negative integer number num. For every numbers i in the range 0
# i num calculate the number of 1's in their binary representation and return
# them as an array.
#
# Example 1:
#
# Input: 2
# Output: [0,1,1]
#
# Example 2:
#
# Input: 5
# Output: [0,1,1,2,1,2]
#
#
# Follow up:
#
#
# It is very easy to come up with a solution with run time
# O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a
# single pass?
# Space complexity should be O(n).
# Can you do it like a boss? Do it without using any builtin function like
# __builtin_popcount in c++ or in any other language.# Time: O(n)
# Space: O(n)
class Solution(object):
def countBits(self, num):
"""
:type num: int
:rtype: List[int]
"""
res = [0]
for i in xrange(1, num + 1):
# Number of 1's in i = (i & 1) + number of 1's in (i / 2).
res.append((i & 1) + res[i >> 1])
return res
344
stone-game-ii.py
# Alex and Lee continue their games with piles of stones. There are a number
# of piles arranged in a row, and each pile has a positive integer number of
# stones piles[i]. The objective of the game is to end with the most stones.
#
# Alex and Lee take turns, with Alex starting first. Initially, M = 1.
#
# On each player's turn, that player can take all the stones in the first X
# remaining piles, where 1 <= X <= 2M. Then, we set M = max(M, X).
#
# The game continues until all the stones have been taken.
#
# Assuming Alex and Lee play optimally, return the maximum number of stones Alex
# can get.
#
#
# Example 1:
#
# Input: piles = [2,7,9,4,4]
# Output: 10
# Explanation: If Alex takes one pile at the beginning, Lee takes two piles,
# then Alex takes 2 piles again. Alex can get 2 + 4 + 4 = 10 piles in total. If
# Alex takes two piles at the beginning, then Lee can take all three piles left.
# In this case, Alex get 2 + 7 = 9 piles in total. So we return 10 since it's
# larger.
#
#
#
# Constraints:
#
#
# 1 <= piles.length <= 100
# 1 <= piles[i] <= 10 ^ 4# Time: O(n*(logn)^2)
# Space: O(nlogn)
class Solution(object):
def stoneGameII(self, piles):
"""
:type piles: List[int]
:rtype: int
"""
def dp(piles, lookup, i, m):
if i+2*m >= len(piles):
return piles[i]
if (i, m) not in lookup:
lookup[i, m] = piles[i] - \
min(dp(piles, lookup, i+x, max(m, x))
for x in xrange(1, 2*m+1))
return lookup[i, m]
for i in reversed(xrange(len(piles)-1)):
piles[i] += piles[i+1]
return dp(piles, {}, 0, 1)
345
lru-cache.py
# Design and implement a data structure for Least Recently Used (LRU) cache. It
# should support the following operations: get and put.
#
# get(key) - Get the value (will always be positive) of the key if the key
# exists in the cache, otherwise return -1.
#
# put(key, value) - Set or insert the value if the key is not already present.
# When the cache reached its capacity, it should invalidate the least recently
# used item before inserting a new item.
#
# The cache is initialized with a positive capacity.
#
# Follow up:
#
# Could you do both operations in O(1) time complexity?
#
# Example:
#
# LRUCache cache = new LRUCache( 2 /* capacity */ );
#
# cache.put(1, 1);
# cache.put(2, 2);
# cache.get(1); // returns 1
# cache.put(3, 3); // evicts key 2
# cache.get(2); // returns -1 (not found)
# cache.put(4, 4); // evicts key 1
# cache.get(1); // returns -1 (not found)
# cache.get(3); // returns 3
# cache.get(4); // returns 4# Time: O(1), per operation.
# Space: O(k), k is the capacity of cache.
class ListNode(object):
def __init__(self, key, val):
self.val = val
self.key = key
self.next = None
self.prev = None
class LinkedList(object):
def __init__(self):
self.head = None
self.tail = None
346
node.next.prev = node.prev
else:
self.tail = node.prev
node.next, node.prev = None, None # make node clean
class LRUCache(object):
# @return an integer
def get(self, key):
if key in self.dict:
val = self.dict[key].val
self.list.delete(self.dict[key])
self._insert(key, val)
return val
return -1
import collections
class LRUCache2(object):
def __init__(self, capacity):
self.cache = collections.OrderedDict()
self.capacity = capacity
347
self.cache[key] = value
348
maximum-product-of-splitted-binary-tree.py
# Given a binary tree root. Split the binary tree into two subtrees by
# removing 1 edge such that the product of the sums of the subtrees are maximized.
#
# Since the answer may be too large, return it modulo 10^9 + 7.
#
#
# Example 1:
#
#
#
# Input: root = [1,2,3,4,5,6]
# Output: 110
# Explanation: Remove the red edge and get 2 binary trees with sum 11 and 10.
# Their product is 110 (11*10)
#
#
# Example 2:
#
#
#
# Input: root = [1,null,2,3,4,null,null,5,6]
# Output: 90
# Explanation: Remove the red edge and get 2 binary trees with sum 15 and
# 6.Their product is 90 (15*6)
#
#
# Example 3:
#
# Input: root = [2,3,9,10,7,8,6,5,4,11,1]
# Output: 1025
#
#
# Example 4:
#
# Input: root = [1,1]
# Output: 1
#
#
#
# Constraints:
#
#
# Each tree has at most 50000 nodes and at least 2 nodes.
# Each node's value is between [1, 10000].# Time: O(n)
# Space: O(h)
class Solution(object):
def maxProduct(self, root):
"""
:type root: TreeNode
349
:rtype: int
"""
MOD = 10**9 + 7
def dfs(root, total, result):
if not root:
return 0
subtotal = dfs(root.left, total, result)+dfs(root.right, total, result)+root.val
result[0] = max(result[0], subtotal*(total-subtotal) )
return subtotal
result = [0]
dfs(root, dfs(root, 0, result), result)
return result[0] % MOD
350
valid-tic-tac-toe-state.py
# A Tic-Tac-Toe board is given as a string array board. Return True if and only
# if it is possible to reach this board position during the course of a valid tic-
# tac-toe game.
#
# The board is a 3 x 3 array, and consists of characters " ", "X", and "O". The
# " " character represents an empty square.
#
# Here are the rules of Tic-Tac-Toe:
#
#
# Players take turns placing characters into empty squares (" ").
# The first player always places "X" characters, while the second player
# always places "O" characters.
# "X" and "O" characters are always placed into empty squares, never
# filled ones.
# The game ends when there are 3 of the same (non-empty) character filling
# any row, column, or diagonal.
# The game also ends if all squares are non-empty.
# No more moves can be played if the game is over.
#
#
# Example 1:
# Input: board = ["O ", " ", " "]
# Output: false
# Explanation: The first player always plays "X".
#
# Example 2:
# Input: board = ["XOX", " X ", " "]
# Output: false
# Explanation: Players take turns making moves.
#
# Example 3:
# Input: board = ["XXX", " ", "OOO"]
# Output: false
#
# Example 4:
# Input: board = ["XOX", "O O", "XOX"]
# Output: true
#
#
# Note:
#
#
# board is a length-3 array of strings, where each string board[i] has
# length 3.
# Each board[i][j] is a character in the set {" ", "X", "O"}.# Time: O(1)
# Space: O(1)
class Solution(object):
def validTicTacToe(self, board):
"""
:type board: List[str]
:rtype: bool
"""
def win(board, player):
for i in xrange(3):
if all(board[i][j] == player for j in xrange(3)):
return True
351
if all(board[j][i] == player for j in xrange(3)):
return True
return True
352
decrease-elements-to-make-array-zigzag.py
# Given an array nums of integers, a move consists of choosing any element and
# decreasing it by 1.
#
# An array A is a zigzag array if either:
#
#
# Every even-indexed element is greater than adjacent elements, ie. A[0] >
# A[1] < A[2] > A[3] < A[4] > ...
# OR, every odd-indexed element is greater than adjacent elements,
# ie. A[0] < A[1] > A[2] < A[3] > A[4] < ...
#
#
# Return the minimum number of moves to transform the given array nums into a
# zigzag array.
#
#
# Example 1:
#
# Input: nums = [1,2,3]
# Output: 2
# Explanation: We can decrease 2 to 0 or 3 to 1.
#
#
# Example 2:
#
# Input: nums = [9,6,1,6,2]
# Output: 4
#
#
#
# Constraints:
#
#
# 1 <= nums.length <= 1000
# 1 <= nums[i] <= 1000# Time: O(n)
# Space: O(1)
class Solution(object):
def movesToMakeZigzag(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
result = [0, 0]
for i in xrange(len(nums)):
left = nums[i-1] if i-1 >= 0 else float("inf")
right = nums[i+1] if i+1 < len(nums) else float("inf")
result[i%2] += max(nums[i] - min(left, right) + 1, 0)
return min(result)
353
maximum-xor-of-two-numbers-in-an-array.py
# Given a non-empty array of numbers, a0, a1, a2, ... , an-1, where 0 ai < 231.
#
# Find the maximum result of ai XOR aj, where 0 i, j < n.
#
# Could you do this in O(n) runtime?
#
# Example:
#
# Input: [3, 10, 5, 25, 2, 8]
#
# Output: 28
#
# Explanation: The maximum result is 5 ^ 25 = 28.# Time: O(n)
# Space: O(n)
class Solution(object):
def findMaximumXOR(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
result = 0
for i in reversed(xrange(32)):
result <<= 1
prefixes = set()
for n in nums:
prefixes.add(n >> i)
for p in prefixes:
if (result | 1) ^ p in prefixes:
result += 1
break
return result
354
longest-common-subsequence.py
# Given two strings text1 and text2, return the length of their longest common
# subsequence.
#
# A subsequence of a string is a new string generated from the original string
# with some characters(can be none) deleted without changing the relative order of
# the remaining characters. (eg, "ace" is a subsequence of "abcde" while "aec" is
# not). A common subsequence of two strings is a subsequence that is common to
# both strings.
#
#
#
# If there is no common subsequence, return 0.
#
#
# Example 1:
#
# Input: text1 = "abcde", text2 = "ace"
# Output: 3
# Explanation: The longest common subsequence is "ace" and its length is 3.
#
#
# Example 2:
#
# Input: text1 = "abc", text2 = "abc"
# Output: 3
# Explanation: The longest common subsequence is "abc" and its length is 3.
#
#
# Example 3:
#
# Input: text1 = "abc", text2 = "def"
# Output: 0
# Explanation: There is no such common subsequence, so the result is 0.
#
#
#
# Constraints:
#
#
# 1 <= text1.length <= 1000
# 1 <= text2.length <= 1000
# The input strings consist of lowercase English characters only.# Time: O(m * n)
# Space: O(min(m, n))
class Solution(object):
def longestCommonSubsequence(self, text1, text2):
"""
:type text1: str
:type text2: str
:rtype: int
"""
if len(text1) < len(text2):
return self.longestCommonSubsequence(text2, text1)
355
else max(dp[(i-1)%2][j], dp[i%2][j-1])
return dp[len(text1)%2][len(text2)]
356
binary-tree-inorder-traversal.py
# Given a binary tree, return the inorder traversal of its nodes' values.
#
# Example:
#
# Input: [1,null,2,3]
# 1
# \
# 2
# /
# 3
#
# Output: [1,3,2]
#
# Follow up: Recursive solution is trivial, could you do it iteratively?# Time: O(n)
# Space: O(1)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
if node.right is None:
node.right = curr
curr = curr.left
else:
result.append(curr.val)
node.right = None
curr = curr.right
return result
# Time: O(n)
# Space: O(h)
# Stack Solution
class Solution2(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
357
:rtype: List[int]
"""
result, stack = [], [(root, False)]
while stack:
root, is_visited = stack.pop()
if root is None:
continue
if is_visited:
result.append(root.val)
else:
stack.append((root.right, False))
stack.append((root, True))
stack.append((root.left, False))
return result
358
sort-the-matrix-diagonally.py
# Given a m * n matrix mat of integers, sort it diagonally in ascending order
# from the top-left to the bottom-right then return the sorted array.
#
#
# Example 1:
#
# Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
# Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]
#
#
#
# Constraints:
#
#
# m == mat.length
# n == mat[i].length
# 1 <= m, n <= 100
# 1 <= mat[i][j] <= 100# Time: O(m * n * log(min(m, n))
# Space: O(m * n)
import collections
class Solution(object):
def diagonalSort(self, mat):
"""
:type mat: List[List[int]]
:rtype: List[List[int]]
"""
lookup = collections.defaultdict(list)
for i in xrange(len(mat)):
for j in xrange(len(mat[0])):
lookup[i-j].append(mat[i][j])
for v in lookup.itervalues():
v.sort()
for i in reversed(xrange(len(mat))):
for j in reversed(xrange(len(mat[0]))):
mat[i][j] = lookup[i-j].pop()
return mat
359
flip-binary-tree-to-match-preorder-traversal.py
# Example 2:
#
#
#
# Input: root = [1,2,3], voyage = [1,3,2]
# Output: [1]
#
#
#
# Example 3:
#
#
#
# Input: root = [1,2,3], voyage = [1,2,3]
# Output: []
#
#
#
#
# Note:
#
#
# 1 <= N <= 100# Time: O(n)
# Space: O(h)
class Solution(object):
def flipMatchVoyage(self, root, voyage):
"""
:type root: TreeNode
:type voyage: List[int]
:rtype: List[int]
"""
def dfs(root, voyage, i, result):
if not root:
return True
if root.val != voyage[i[0]]:
return False
i[0] += 1
if root.left and root.left.val != voyage[i[0]]:
result.append(root.val)
return dfs(root.right, voyage, i, result) and \
dfs(root.left, voyage, i, result)
return dfs(root.left, voyage, i, result) and \
dfs(root.right, voyage, i, result)
result = []
return result if dfs(root, voyage, [0], result) else [-1]
360
bulb-switcher-ii.py
# There is a room with n lights which are turned on initially and 4 buttons on
# the wall. After performing exactly m unknown operations towards buttons, you
# need to return how many different kinds of status of the n lights could be.
#
# Suppose n lights are labeled as number [1, 2, 3 ..., n], function of these 4
# buttons are given below:
#
#
# Flip all the lights.
# Flip lights with even numbers.
# Flip lights with odd numbers.
# Flip lights with (3k + 1) numbers, k = 0, 1, 2, ...
#
#
#
#
# Example 1:
#
# Input: n = 1, m = 1.
# Output: 2
# Explanation: Status can be: [on], [off]
#
#
#
#
# Example 2:
#
# Input: n = 2, m = 1.
# Output: 3
# Explanation: Status can be: [on, off], [off, on], [off, off]
#
#
#
#
# Example 3:
#
# Input: n = 3, m = 1.
# Output: 4
# Explanation: Status can be: [off, on, off], [on, off, on], [off, off, off],
# [off, on, on].
#
#
#
#
# Note: n and m both fit in range [0, 1000].# Time: O(1)
# Space: O(1)
class Solution(object):
def flipLights(self, n, m):
"""
:type n: int
:type m: int
:rtype: int
"""
if m == 0:
return 1
if n == 1:
return 2
361
if m == 1 and n == 2:
return 3
if m == 1 or n == 2:
return 4
if m == 2:
return 7
return 8
362
arithmetic-slices.py
# A sequence of numbers is called arithmetic if it consists of at least three
# elements and if the difference between any two consecutive elements is the same.
#
# For example, these are arithmetic sequences:
#
# 1, 3, 5, 7, 9
# 7, 7, 7, 7
# 3, -1, -5, -9
#
# The following sequence is not arithmetic.
#
# 1, 1, 2, 5, 7
#
#
# A zero-indexed array A consisting of N numbers is given. A slice of that array
# is any pair of integers (P, Q) such that 0 <= P < Q < N.
#
# A slice (P, Q) of the array A is called arithmetic if the sequence:
#
# A[P], A[P + 1], ..., A[Q - 1], A[Q] is arithmetic. In particular, this means
# that P + 1 < Q.
#
# The function should return the number of arithmetic slices in the array A.
#
#
# Example:
#
# A = [1, 2, 3, 4]
#
# return: 3, for 3 arithmetic slices in A: [1, 2, 3], [2, 3, 4] and [1, 2, 3, 4]
# itself.# Time: O(n)
# Space: O(1)
class Solution(object):
def numberOfArithmeticSlices(self, A):
"""
:type A: List[int]
:rtype: int
"""
res, i = 0, 0
while i+2 < len(A):
start = i
while i+2 < len(A) and A[i+2] + A[i] == 2*A[i+1]:
res += i - start + 1
i += 1
i += 1
return res
363
unique-paths.py
# A robot is located at the top-left corner of a m x n grid (marked 'Start' in
# the diagram below).
#
# The robot can only move either down or right at any point in time. The robot
# is trying to reach the bottom-right corner of the grid (marked 'Finish' in the
# diagram below).
#
# How many possible unique paths are there?
#
#
#
# Above is a 7 x 3 grid. How many possible unique paths are there?
#
#
# Example 1:
#
# Input: m = 3, n = 2
# Output: 3
# Explanation:
# From the top-left corner, there are a total of 3 ways to reach the bottom-
# right corner:
# 1. Right -> Right -> Down
# 2. Right -> Down -> Right
# 3. Down -> Right -> Right
#
#
# Example 2:
#
# Input: m = 7, n = 3
# Output: 28
#
#
#
# Constraints:
#
#
# 1 <= m, n <= 100
# It's guaranteed that the answer will be less than or equal to 2 * 10 ^
# 9.# Time: O(m * n)
# Space: O(m + n)
class Solution(object):
# @return an integer
def uniquePaths(self, m, n):
if m < n:
return self.uniquePaths(n, m)
ways = [1] * n
return ways[n - 1]
364
bag-of-tokens.py
# Example 2:
#
# Input: tokens = [100,200], P = 150
# Output: 1
#
#
#
# Example 3:
#
# Input: tokens = [100,200,300,400], P = 200
# Output: 2
#
#
#
#
# Note:
#
#
# tokens.length <= 1000
# 0 <= tokens[i] < 10000
# 0 <= P < 10000# Time: O(nlogn)
# Space: O(1)
class Solution(object):
def bagOfTokensScore(self, tokens, P):
"""
:type tokens: List[int]
:type P: int
:rtype: int
"""
tokens.sort()
result, points = 0, 0
left, right = 0, len(tokens)-1
while left <= right:
if P >= tokens[left]:
P -= tokens[left]
left += 1
points += 1
result = max(result, points)
elif points > 0:
points -= 1
P += tokens[right]
right -= 1
else:
break
return result
365
decode-ways.py
# A message containing letters from A-Z is being encoded to numbers using the
# following mapping:
#
# 'A' -> 1
# 'B' -> 2
# ...
# 'Z' -> 26
#
#
# Given a non-empty string containing only digits, determine the total number of
# ways to decode it.
#
# Example 1:
#
# Input: "12"
# Output: 2
# Explanation: It could be decoded as "AB" (1 2) or "L" (12).
#
#
# Example 2:
#
# Input: "226"
# Output: 3
# Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2
# 6).# Time: O(n)
# Space: O(1)
class Solution(object):
def numDecodings(self, s):
"""
:type s: str
:rtype: int
"""
if len(s) == 0 or s[0] == '0':
return 0
prev, prev_prev = 1, 0
for i in xrange(len(s)):
cur = 0
if s[i] != '0':
cur = prev
if i > 0 and (s[i - 1] == '1' or (s[i - 1] == '2' and s[i] <= '6')):
cur += prev_prev
prev, prev_prev = cur, prev
return prev
366
statistics-from-a-large-sample.py
# We sampled integers between 0 and 255, and stored the results in an array
# count: count[k] is the number of integers we sampled equal to k.
#
# Return the minimum, maximum, mean, median, and mode of the sample
# respectively, as an array of floating point numbers. The mode is guaranteed to
# be unique.
#
# (Recall that the median of a sample is:
#
#
# The middle element, if the elements of the sample were sorted and the
# number of elements is odd;
# The average of the middle two elements, if the elements of the sample
# were sorted and the number of elements is even.)
#
#
#
# Example 1:
# Input: count = [0,1,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
# Output: [1.00000,3.00000,2.37500,2.50000,3.00000]
# Example 2:
# Input: count = [0,4,3,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
# 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
# Output: [1.00000,4.00000,2.18182,2.00000,1.00000]
#
#
# Constraints:
#
#
# count.length == 256
# 1 <= sum(count) <= 10^9
# The mode of the sample that count represents is unique.
# Answers within 10^-5 of the true value will be accepted as correct.# Time: O(n)
# Space: O(1)
import bisect
class Solution(object):
def sampleStats(self, count):
"""
:type count: List[int]
:rtype: List[float]
"""
n = sum(count)
mi = next(i for i in xrange(len(count)) if count[i]) * 1.0
ma = next(i for i in reversed(xrange(len(count))) if count[i]) * 1.0
367
mean = sum(i * v for i, v in enumerate(count)) * 1.0 / n
mode = count.index(max(count)) * 1.0
for i in xrange(1, len(count)):
count[i] += count[i-1]
median1 = bisect.bisect_left(count, (n+1) // 2)
median2 = bisect.bisect_left(count, (n+2) // 2)
median = (median1+median2) / 2.0
return [mi, ma, mean, median, mode]
368
array-nesting.py
# A zero-indexed array A of length N contains all integers from 0 to N-1. Find
# and return the longest length of set S, where S[i] = {A[i], A[A[i]], A[A[A[i]]],
# ... } subjected to the rule below.
#
# Suppose the first element in S starts with the selection of element A[i] of
# index = i, the next element in S should be A[A[i]], and then A[A[A[i]]]... By that
# analogy, we stop adding right before a duplicate element occurs in S.
#
#
#
# Example 1:
#
# Input: A = [5,4,0,3,1,6,2]
# Output: 4
# Explanation:
# A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2.
#
# One of the longest S[K]:
# S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0}
#
#
#
#
# Note:
#
#
# N is an integer within the range [1, 20,000].
# The elements of A are all distinct.
# Each element of A is an integer within the range [0, N-1].# Time: O(n)
# Space: O(1)
class Solution(object):
def arrayNesting(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
result = 0
for num in nums:
if num is not None:
start, count = num, 0
while nums[start] is not None:
temp = start
start = nums[start]
nums[temp] = None
count += 1
result = max(result, count)
return result
369
divide-two-integers.py
# Given two integers dividend and divisor, divide two integers without using
# multiplication, division and mod operator.
#
# Return the quotient after dividing dividend by divisor.
#
# The integer division should truncate toward zero, which means losing its
# fractional part. For example, truncate(8.345) = 8 and truncate(-2.7335) = -2.
#
# Example 1:
#
# Input: dividend = 10, divisor = 3
# Output: 3
# Explanation: 10/3 = truncate(3.33333..) = 3.
#
#
# Example 2:
#
# Input: dividend = 7, divisor = -3
# Output: -2
# Explanation: 7/-3 = truncate(-2.33333..) = -2.
#
#
# Note:
#
#
# Both dividend and divisor will be 32-bit signed integers.
# The divisor will never be 0.
# Assume we are dealing with an environment which could only store
# integers within the 32-bit signed integer range: [231, 231 1]. For the
# purpose of this problem, assume that your function returns 231 1 when the
# division result overflows.# Time: O(logn) = O(1)
# Space: O(1)
class Solution(object):
def divide(self, dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
"""
result, dvd, dvs = 0, abs(dividend), abs(divisor)
while dvd >= dvs:
inc = dvs
i = 0
while dvd >= inc:
dvd -= inc
result += 1 << i
inc <<= 1
i += 1
if dividend > 0 and divisor < 0 or dividend < 0 and divisor > 0:
return -result
else:
return result
370
:rtype: int
"""
positive = (dividend < 0) is (divisor < 0)
dividend, divisor = abs(dividend), abs(divisor)
res = 0
while dividend >= divisor:
temp, i = divisor, 1
while dividend >= temp:
dividend -= temp
res += i
i <<= 1
temp <<= 1
if not positive:
res = -res
return min(max(-2147483648, res), 2147483647)
371
coin-change.py
# You are given coins of different denominations and a total amount of money
# amount. Write a function to compute the fewest number of coins that you need to
# make up that amount. If that amount of money cannot be made up by any
# combination of the coins, return -1.
#
# Example 1:
#
# Input: coins = [1, 2, 5], amount = 11
# Output: 3
# Explanation: 11 = 5 + 5 + 1
#
# Example 2:
#
# Input: coins = [2], amount = 3
# Output: -1
#
#
# Note:
#
# You may assume that you have an infinite number of each kind of coin.# Time: O(n * k), n is the number of co
# Space: O(k)
class Solution(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
INF = 0x7fffffff # Using float("inf") would be slower.
amounts = [INF] * (amount + 1)
amounts[0] = 0
for i in xrange(amount + 1):
if amounts[i] != INF:
for coin in coins:
if i + coin <= amount:
amounts[i + coin] = min(amounts[i + coin], amounts[i] + 1)
return amounts[amount] if amounts[amount] != INF else -1
372
regions-cut-by-slashes.py
# Example 3:
#
# Input:
# [
# "\\/",
# "/\\"
# ]
# Output: 4
# Explanation: (Recall that because \ characters are escaped, "\\/" refers to
# \/, and "/\\" refers to /\.)
# The 2x2 grid is as follows:
#
#
#
#
# Example 4:
#
# Input:
# [
# "/\\",
# "\\/"
# ]
# Output: 5
# Explanation: (Recall that because \ characters are escaped, "/\\" refers to
# /\, and "\\/" refers to \/.)
# The 2x2 grid is as follows:
#
#
#
#
# Example 5:
#
# Input:
# [
# "//",
# "/ "
# ]
# Output: 3
# Explanation: The 2x2 grid is as follows:
#
#
#
#
#
# Note:
#
#
# 1 <= grid.length == grid[0].length <= 30
# grid[i][j] is either '/', '\', or ' '.# Time: O(n^2)
# Space: O(n^2)
class UnionFind(object):
def __init__(self, n):
self.set = range(n)
self.count = n
373
self.set[x] = self.find_set(self.set[x]) # path compression.
return self.set[x]
class Solution(object):
def regionsBySlashes(self, grid):
"""
:type grid: List[str]
:rtype: int
"""
def index(n, i, j, k):
return (i*n + j)*4 + k
union_find = UnionFind(len(grid)**2 * 4)
N, E, S, W = range(4)
for i in xrange(len(grid)):
for j in xrange(len(grid)):
if i:
union_find.union_set(index(len(grid), i-1, j, S),
index(len(grid),i, j, N))
if j:
union_find.union_set(index(len(grid), i, j-1, E),
index(len(grid), i, j, W))
if grid[i][j] != "/":
union_find.union_set(index(len(grid), i, j, N),
index(len(grid), i, j, E))
union_find.union_set(index(len(grid), i, j, S),
index(len(grid), i, j, W))
if grid[i][j] != "\\":
union_find.union_set(index(len(grid), i, j, W),
index(len(grid), i, j, N))
union_find.union_set(index(len(grid), i, j, E),
index(len(grid), i, j, S))
return union_find.count
374
letter-combinations-of-a-phone-number.py
# Given a string containing digits from 2-9 inclusive, return all possible
# letter combinations that the number could represent.
#
# A mapping of digit to letters (just like on the telephone buttons) is given
# below. Note that 1 does not map to any letters.
#
#
#
# Example:
#
# Input: "23"
# Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
#
#
# Note:
#
# Although the above answer is in lexicographical order, your answer could be in
# any order you want.# Time: O(n * 4^n)
# Space: O(n)
class Solution(object):
# @return a list of strings, [s1, s2]
def letterCombinations(self, digits):
if not digits:
return []
return result
375
self.letterCombinationsRecu(result, digits, lookup, cur + choice, n + 1)
376
longest-repeating-character-replacement.py
# Given a string s that consists of only uppercase English letters, you can
# perform at most k operations on that string.
#
# In one operation, you can choose any character of the string and change it to
# any other uppercase English character.
#
# Find the length of the longest sub-string containing all repeating letters you
# can get after performing the above operations.
#
# Note:
#
# Both the string's length and k will not exceed 104.
#
# Example 1:
#
# Input:
# s = "ABAB", k = 2
#
# Output:
# 4
#
# Explanation:
# Replace the two 'A's with two 'B's or vice versa.
#
#
#
#
# Example 2:
#
# Input:
# s = "AABABBA", k = 1
#
# Output:
# 4
#
# Explanation:
# Replace the one 'A' in the middle with 'B' and form "AABBBBA".
# The substring "BBBB" has the longest repeating letters, which is 4.# Time: O(n)
# Space: O(1)
import collections
class Solution(object):
def characterReplacement(self, s, k):
"""
:type s: str
:type k: int
:rtype: int
"""
result, max_count = 0, 0
count = collections.Counter()
for i in xrange(len(s)):
count[s[i]] += 1
max_count = max(max_count, count[s[i]])
if result - max_count >= k:
count[s[i-result]] -= 1
else:
377
result += 1
return result
378
search-in-rotated-sorted-array.py
# Given an integer array nums sorted in ascending order, and an integer target.
#
# Suppose that nums is rotated at some pivot unknown to you beforehand (i.e.,
# [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
#
# You should search for target in nums and if you found return its index,
# otherwise return -1.
#
#
# Example 1:
# Input: nums = [4,5,6,7,0,1,2], target = 0
# Output: 4
# Example 2:
# Input: nums = [4,5,6,7,0,1,2], target = 3
# Output: -1
# Example 3:
# Input: nums = [1], target = 0
# Output: -1
#
#
# Constraints:
#
#
# 1 <= nums.length <= 5000
# -10^4 <= nums[i] <= 10^4
# All values of nums are unique.
# nums is guranteed to be rotated at some pivot.
# -10^4 <= target <= 10^4# Time: O(logn)
# Space: O(1)
class Solution(object):
def search(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left, right = 0, len(nums) - 1
if nums[mid] == target:
return mid
elif (nums[mid] >= nums[left] and nums[left] <= target < nums[mid]) or \
(nums[mid] < nums[left] and not (nums[mid] < target <= nums[right])):
right = mid - 1
else:
left = mid + 1
return -1
379
increasing-triplet-subsequence.py
# Given an unsorted array return whether an increasing subsequence of length 3
# exists or not in the array.
#
# Formally the function should:
#
# Return true if there exists i, j, k
#
# such that arr[i] < arr[j] < arr[k] given 0 i < j < k n-1 else return
# false.
#
# Note: Your algorithm should run in O(n) time complexity and O(1) space
# complexity.
#
#
# Example 1:
#
# Input: [1,2,3,4,5]
# Output: true
#
#
#
# Example 2:
#
# Input: [5,4,3,2,1]
# Output: false# Time: O(n)
# Space: O(1)
import bisect
class Solution(object):
def increasingTriplet(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
min_num, a, b = float("inf"), float("inf"), float("inf")
for c in nums:
if min_num >= c:
min_num = c
elif b >= c:
a, b = min_num, c
else: # a < b < c
return True
return False
380
i = bisect.bisect_left(inc, num)
if i >= k - 1:
return True
inc[i] = num
return k == 0
return increasingKUplet(nums, 3)
381
permutations-ii.py
# Given a collection of numbers that might contain duplicates, return all
# possible unique permutations.
#
# Example:
#
# Input: [1,1,2]
# Output:
# [
# [1,1,2],
# [1,2,1],
# [2,1,1]
# ]# Time: O(n * n!)
# Space: O(n)
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
result = []
used = [False] * len(nums)
self.permuteUniqueRecu(result, used, [], nums)
return result
class Solution2(object):
# @param num, a list of integer
# @return a list of lists of integers
def permuteUnique(self, nums):
solutions = [[]]
solutions = next
return solutions
382
find-and-replace-pattern.py
# You have a list of words and a pattern, and you want to know which words in
# words matches the pattern.
#
# A word matches the pattern if there exists a permutation of letters p so that
# after replacing every letter x in the pattern with p(x), we get the desired
# word.
#
# (Recall that a permutation of letters is a bijection from letters to letters:
# every letter maps to another letter, and no two letters map to the same letter.)
#
# Return a list of the words in words that match the given pattern.
#
# You may return the answer in any order.
#
#
#
#
# Example 1:
#
# Input: words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"
# Output: ["mee","aqq"]
# Explanation: "mee" matches the pattern because there is a permutation {a -> m,
# b -> e, ...}.
# "ccc" does not match the pattern because {a -> c, b -> c, ...} is not a
# permutation,
# since a and b map to the same letter.
#
#
#
# Note:
#
#
# 1 <= words.length <= 50
# 1 <= pattern.length = words[i].length <= 20# Time: O(n * l)
# Space: O(1)
import itertools
class Solution(object):
def findAndReplacePattern(self, words, pattern):
"""
:type words: List[str]
:type pattern: str
:rtype: List[str]
"""
def match(word):
lookup = {}
for x, y in itertools.izip(pattern, word):
if lookup.setdefault(x, y) != y:
return False
return len(set(lookup.values())) == len(lookup.values())
383
time-based-key-value-store.py
# Create a timebased key-value store class TimeMap, that supports two
# operations.
#
# 1. set(string key, string value, int timestamp)
#
#
# Stores the key and value, along with the given timestamp.
#
#
# 2. get(string key, int timestamp)
#
#
# Returns a value such that set(key, value, timestamp_prev) was called
# previously, with timestamp_prev <= timestamp.
# If there are multiple such values, it returns the one with the largest
# timestamp_prev.
# If there are no values, it returns the empty string ("").
#
#
#
#
#
# Example 1:
#
# Input: inputs = ["TimeMap","set","get","get","set","get","get"], inputs =
# [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]]
# Output: [null,null,"bar","bar",null,"bar2","bar2"]
# Explanation:
# TimeMap kv;
# kv.set("foo", "bar", 1); // store the key "foo" and value "bar" along with
# timestamp = 1
# kv.get("foo", 1); // output "bar"
# kv.get("foo", 3); // output "bar" since there is no value corresponding to foo
# at timestamp 3 and timestamp 2, then the only value is at timestamp 1 ie "bar"
# kv.set("foo", "bar2", 4);
# kv.get("foo", 4); // output "bar2"
# kv.get("foo", 5); //output "bar2"
#
#
#
#
# Example 2:
#
# Input: inputs = ["TimeMap","set","set","get","get","get","get","get"], inputs
# = [[],["love","high",10],["love","low",20],["love",5],["love",10],["love",15],["
# love",20],["love",25]]
# Output: [null,null,null,"","high","high","low","low"]
#
#
#
#
#
#
# Note:
#
#
# All key/value strings are lowercase.
# All key/value strings have length in the range [1, 100]
384
# The timestamps for all TimeMap.set operations are strictly increasing.
# 1 <= timestamp <= 10^7
# TimeMap.set and TimeMap.get functions will be called a total of 120000
# times (combined) per test case.# Time: set: O(1)
# get: O(logn)
# Space: O(n)
import collections
import bisect
class TimeMap(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.lookup = collections.defaultdict(list)
385
ugly-number-iii.py
# Write a program to find the n-th ugly number.
#
# Ugly numbers are positive integers which are divisible by a or b or c.
#
#
# Example 1:
#
# Input: n = 3, a = 2, b = 3, c = 5
# Output: 4
# Explanation: The ugly numbers are 2, 3, 4, 5, 6, 8, 9, 10... The 3rd is 4.
#
# Example 2:
#
# Input: n = 4, a = 2, b = 3, c = 4
# Output: 6
# Explanation: The ugly numbers are 2, 3, 4, 6, 8, 9, 10, 12... The 4th is 6.
#
#
# Example 3:
#
# Input: n = 5, a = 2, b = 11, c = 13
# Output: 10
# Explanation: The ugly numbers are 2, 4, 6, 8, 10, 11, 12, 13... The 5th is 10.
#
#
# Example 4:
#
# Input: n = 1000000000, a = 2, b = 217983653, c = 336916467
# Output: 1999999984
#
#
#
# Constraints:
#
#
# 1 <= n, a, b, c <= 10^9
# 1 <= a * b * c <= 10^18
# It's guaranteed that the result will be in range [1, 2 * 10^9]# Time: O(logn)
# Space: O(1)
class Solution(object):
def nthUglyNumber(self, n, a, b, c):
"""
:type n: int
:type a: int
:type b: int
:type c: int
:rtype: int
"""
def gcd(a, b):
while b:
a, b = b, a % b
return a
386
return x//a + x//b + x//c - (x//lcm_a_b + x//lcm_b_c + x//lcm_c_a) + x//lcm_a_b_c
387
utf-8-validation.py
# A character in UTF8 can be from 1 to 4 bytes long, subjected to the following
# rules:
#
# For 1-byte character, the first bit is a 0, followed by its unicode code.
# For n-bytes character, the first n-bits are all one's, the n+1 bit is 0,
# followed by n-1 bytes with most significant 2 bits being 10.
#
# This is how the UTF-8 encoding would work:
#
# Char. number range | UTF-8 octet sequence
# (hexadecimal) | (binary)
# --------------------+---------------------------------------------
# 0000 0000-0000 007F | 0xxxxxxx
# 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
# 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
# 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
#
#
# Given an array of integers representing the data, return whether it is a valid
# utf-8 encoding.
#
#
# Note:
#
# The input is an array of integers. Only the least significant 8 bits of each
# integer is used to store the data. This means each integer represents only 1
# byte of data.
#
#
#
# Example 1:
# data = [197, 130, 1], which represents the octet sequence: 11000101 10000010
# 00000001.
#
# Return true.
# It is a valid utf-8 encoding for a 2-bytes character followed by a 1-byte
# character.
#
#
#
#
# Example 2:
# data = [235, 140, 4], which represented the octet sequence: 11101011 10001100
# 00000100.
#
# Return false.
# The first 3 bits are all one's and the 4th bit is 0 means it is a 3-bytes
# character.
# The next byte is a continuation byte which starts with 10 and that's correct.
# But the second continuation byte does not start with 10, so it is invalid.# Time: O(n)
# Space: O(1)
class Solution(object):
def validUtf8(self, data):
"""
:type data: List[int]
:rtype: bool
"""
388
count = 0
for c in data:
if count == 0:
if (c >> 5) == 0b110:
count = 1
elif (c >> 4) == 0b1110:
count = 2
elif (c >> 3) == 0b11110:
count = 3
elif (c >> 7):
return False
else:
if (c >> 6) != 0b10:
return False
count -= 1
return count == 0
389
longest-increasing-subsequence.py
# Given an unsorted array of integers, find the length of longest increasing
# subsequence.
#
# Example:
#
# Input: [10,9,2,5,3,7,101,18]
# Output: 4
# Explanation: The longest increasing subsequence is [2,3,7,101], therefore the
# length is 4.
#
# Note:
#
#
# There may be more than one LIS combination, it is only necessary for you
# to return the length.
# Your algorithm should run in O(n2) complexity.
#
#
# Follow up: Could you improve it to O(n log n) time complexity?# Time: O(nlogn)
# Space: O(n)
class Solution(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
LIS = []
def insert(target):
left, right = 0, len(LIS) - 1
# Find the first index "left" which satisfies LIS[left] >= target
while left <= right:
mid = left + (right - left) // 2
if LIS[mid] >= target:
right = mid - 1
else:
left = mid + 1
# If not found, append the target.
if left == len(LIS):
LIS.append(target)
else:
LIS[left] = target
return len(LIS)
# Time: O(n^2)
# Space: O(n)
# Traditional DP solution.
class Solution2(object):
def lengthOfLIS(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dp = [] # dp[i]: the length of LIS ends with nums[i]
390
for i in xrange(len(nums)):
dp.append(1)
for j in xrange(i):
if nums[j] < nums[i]:
dp[i] = max(dp[i], dp[j] + 1)
return max(dp) if dp else 0
391
last-stone-weight-ii.py
# We have a collection of rocks, each rock has a positive integer weight.
#
# Each turn, we choose any two rocks and smash them together. Suppose the
# stones have weights x and y with x <= y. The result of this smash is:
#
#
# If x == y, both stones are totally destroyed;
# If x != y, the stone of weight x is totally destroyed, and the stone of
# weight y has new weight y-x.
#
#
# At the end, there is at most 1 stone left. Return the smallest possible
# weight of this stone (the weight is 0 if there are no stones left.)
#
#
#
# Example 1:
#
# Input: [2,7,4,1,8,1]
# Output: 1
# Explanation:
# We can combine 2 and 4 to get 2 so the array converts to [2,7,1,8,1] then,
# we can combine 7 and 8 to get 1 so the array converts to [2,1,1,1] then,
# we can combine 2 and 1 to get 1 so the array converts to [1,1,1] then,
# we can combine 1 and 1 to get 0 so the array converts to [1] then that's the
# optimal value.
#
#
#
#
# Note:
#
#
# 1 <= stones.length <= 30
# 1 <= stones[i] <= 100# Time: O(2^n)
# Space: O(2^n)
class Solution(object):
def lastStoneWeightII(self, stones):
"""
:type stones: List[int]
:rtype: int
"""
dp = {0}
for stone in stones:
dp |= {stone+i for i in dp}
S = sum(stones)
return min(abs(i-(S-i)) for i in dp)
392
largest-number.py
# Given a list of non negative integers, arrange them such that they form the
# largest number.
#
# Example 1:
#
# Input: [10,2]
# Output: "210"
#
# Example 2:
#
# Input: [3,30,34,5,9]
# Output: "9534330"
#
#
# Note: The result may be very large, so you need to return a string instead of
# an integer.# Time: O(nlogn)
# Space: O(1)
class Solution(object):
# @param num, a list of integers
# @return a string
def largestNumber(self, num):
num = [str(x) for x in num]
num.sort(cmp=lambda x, y: cmp(y + x, x + y))
largest = ''.join(num)
return largest.lstrip('0') or '0'
393
coloring-a-border.py
# Example 3:
#
# Input: grid = [[1,1,1],[1,1,1],[1,1,1]], r0 = 1, c0 = 1, color = 2
# Output: [[2, 2, 2], [2, 1, 2], [2, 2, 2]]# Time: O(m * n)
# Space: O(m + n)
import collections
class Solution(object):
def colorBorder(self, grid, r0, c0, color):
"""
:type grid: List[List[int]]
:type r0: int
:type c0: int
:type color: int
:rtype: List[List[int]]
"""
directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]
if is_border:
borders.append((r, c))
for r, c in borders:
grid[r][c] = color
return grid
394
validate-stack-sequences.py
# Example 2:
#
# Input: pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
# Output: false
# Explanation: 1 cannot be popped before 2.# Time: O(n)
# Space: O(n)
class Solution(object):
def validateStackSequences(self, pushed, popped):
"""
:type pushed: List[int]
:type popped: List[int]
:rtype: bool
"""
i = 0
s = []
for v in pushed:
s.append(v)
while s and i < len(popped) and s[-1] == popped[i]:
s.pop()
i += 1
return i == len(popped)
395
4sum.py
# Given an array nums of n integers and an integer target, are there elements a,
# b, c, and d in nums such that a + b + c + d = target? Find all unique
# quadruplets in the array which gives the sum of target.
#
# Note:
#
# The solution set must not contain duplicate quadruplets.
#
# Example:
#
# Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.
#
# A solution set is:
# [
# [-1, 0, 0, 1],
# [-2, -1, 1, 2],
# [-2, 0, 0, 2]
# ]# Time: O(n^3)
# Space: O(1)
import collections
# Time: O(n^2 * p)
396
# Space: O(n^2 * p)
# Hash solution. (224ms)
class Solution2(object):
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
nums, result, lookup = sorted(nums), [], collections.defaultdict(list)
for i in xrange(0, len(nums) - 1):
for j in xrange(i + 1, len(nums)):
is_duplicated = False
for [x, y] in lookup[nums[i] + nums[j]]:
if nums[x] == nums[i]:
is_duplicated = True
break
if not is_duplicated:
lookup[nums[i] + nums[j]].append([i, j])
ans = {}
for c in xrange(2, len(nums)):
for d in xrange(c+1, len(nums)):
if target - nums[c] - nums[d] in lookup:
for [a, b] in lookup[target - nums[c] - nums[d]]:
if b < c:
quad = [nums[a], nums[b], nums[c], nums[d]]
quad_hash = " ".join(str(quad))
if quad_hash not in ans:
ans[quad_hash] = True
result.append(quad)
return result
for i in lookup.keys():
if target - i in lookup:
for x in lookup[i]:
for y in lookup[target - i]:
[a, b], [c, d] = x, y
if a is not c and a is not d and \
b is not c and b is not d:
quad = sorted([nums[a], nums[b], nums[c], nums[d]])
if quad not in result:
result.append(quad)
return sorted(result)
397
bulb-switcher.py
# There are n bulbs that are initially off. You first turn on all the bulbs.
# Then, you turn off every second bulb. On the third round, you toggle every third
# bulb (turning on if it's off or turning off if it's on). For the i-th round, you
# toggle every i bulb. For the n-th round, you only toggle the last bulb. Find how
# many bulbs are on after n rounds.
#
# Example:
#
# Input: 3
# Output: 1
# Explanation:
# At first, the three bulbs are [off, off, off].
# After first round, the three bulbs are [on, on, on].
# After second round, the three bulbs are [on, off, on].
# After third round, the three bulbs are [on, off, off].
#
# So you should return 1, because there is only one bulb is on.# Time: O(1)
# Space: O(1)
import math
class Solution(object):
def bulbSwitch(self, n):
"""
type n: int
rtype: int
"""
# The number of full squares.
return int(math.sqrt(n))
398
path-in-zigzag-labelled-binary-tree.py
# In an infinite binary tree where every node has two children, the nodes are
# labelled in row order.
#
# In the odd numbered rows (ie., the first, third, fifth,...), the labelling is
# left to right, while in the even numbered rows (second, fourth, sixth,...), the
# labelling is right to left.
#
#
#
# Given the label of a node in this tree, return the labels in the path from the
# root of the tree to the node with that label.
#
#
# Example 1:
#
# Input: label = 14
# Output: [1,3,4,14]
#
#
# Example 2:
#
# Input: label = 26
# Output: [1,2,6,10,26]
#
#
#
# Constraints:
#
#
# 1 <= label <= 10^6# Time: O(logn)
# Space: O(logn)
class Solution(object):
def pathInZigZagTree(self, label):
"""
:type label: int
:rtype: List[int]
"""
count = 2**label.bit_length()
result = []
while label >= 1:
result.append(label)
label = ((count//2) + ((count-1)-label)) // 2
count //= 2
result.reverse()
return result
399
break-a-palindrome.py
# Given a palindromic string palindrome, replace exactly one character by any
# lowercase English letter so that the string becomes the lexicographically
# smallest possible string that isn't a palindrome.
#
# After doing so, return the final string. If there is no way to do so, return
# the empty string.
#
#
# Example 1:
#
# Input: palindrome = "abccba"
# Output: "aaccba"
#
#
# Example 2:
#
# Input: palindrome = "a"
# Output: ""
#
#
#
# Constraints:
#
#
# 1 <= palindrome.length <= 1000
# palindrome consists of only lowercase English letters.# Time: O(n)
# Space: O(1)
class Solution(object):
def breakPalindrome(self, palindrome):
"""
:type palindrome: str
:rtype: str
"""
for i in xrange(len(palindrome)//2):
if palindrome[i] != 'a':
return palindrome[:i] + 'a' + palindrome[i+1:]
return palindrome[:-1] + 'b' if len(palindrome) >= 2 else ""
400
balance-a-binary-search-tree.py
# Given a binary search tree, return a balanced binary search tree with the same
# node values.
#
# A binary search tree is balanced if and only if the depth of the two subtrees
# of every node never differ by more than 1.
#
# If there is more than one answer, return any of them.
#
#
# Example 1:
#
#
#
# Input: root = [1,null,2,null,3,null,4,null,null]
# Output: [2,1,3,null,null,null,4]
# Explanation: This is not the only correct answer, [3,1,4,null,2,null,null] is
# also correct.
#
#
#
# Constraints:
#
#
# The number of nodes in the tree is between 1 and 10^4.
# The tree nodes will have distinct values between 1 and 10^5.# Time: O(n)
# Space: O(h)
def sortedArrayToBst(arr):
ROOT, LEFT, RIGHT = range(3)
401
result = [None]
stk = [(0, len(arr), ROOT, result)]
while stk:
i, j, update, ret = stk.pop()
if i >= j:
continue
mid = i + (j-i)//2
node = TreeNode(arr[mid])
if update == ROOT:
ret[0] = node
elif update == LEFT:
ret[0].left = node
else:
ret[0].right = node
stk.append((mid+1, j, RIGHT, [node]))
stk.append((i, mid, LEFT, [node]))
return result[0]
return sortedArrayToBst(inorderTraversal(root))
# Time: O(n)
# Space: O(h)
# dfs solution with recursion
class Solution2(object):
def balanceBST(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
"""
def inorderTraversalHelper(node, arr):
if not node:
return
inorderTraversalHelper(node.left, arr)
arr.append(node.val)
inorderTraversalHelper(node.right, arr)
arr = []
inorderTraversalHelper(root, arr)
return sortedArrayToBstHelper(arr, 0, len(arr))
402
verify-preorder-serialization-of-a-binary-tree.py
# One way to serialize a binary tree is to use pre-order traversal. When we
# encounter a non-null node, we record the node's value. If it is a null node, we
# record using a sentinel value such as #.
#
# _9_
# / \
# 3 2
# / \ / \
# 4 1 # 6
# / \ / \ / \
# # # # # # #
#
#
# For example, the above binary tree can be serialized to the string
# "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents a null node.
#
# Given a string of comma separated values, verify whether it is a correct
# preorder traversal serialization of a binary tree. Find an algorithm without
# reconstructing the tree.
#
# Each comma separated value in the string must be either an integer or a
# character '#' representing null pointer.
#
# You may assume that the input format is always valid, for example it could
# never contain two consecutive commas such as "1,,3".
#
# Example 1:
#
# Input: "9,3,4,#,#,1,#,#,2,#,6,#,#"
# Output: true
#
# Example 2:
#
# Input: "1,#"
# Output: false
#
#
# Example 3:
#
# Input: "9,#,#,1"
# Output: false# Time: O(n)
# Space: O(1)
class Solution(object):
def isValidSerialization(self, preorder):
"""
:type preorder: str
:rtype: bool
"""
def split_iter(s, tok):
start = 0
for i in xrange(len(s)):
if s[i] == tok:
yield s[start:i]
start = i + 1
yield s[start:]
if not preorder:
403
return False
404
valid-triangle-number.py
# Given an array consists of non-negative integers, your task is to count the
# number of triplets chosen from the array that can make triangles if we take them
# as side lengths of a triangle.
#
# Example 1:
#
# Input: [2,2,3,4]
# Output: 3
# Explanation:
# Valid combinations are:
# 2,3,4 (using the first 2)
# 2,3,4 (using the second 2)
# 2,2,3
#
#
#
# Note:
#
#
# The length of the given array won't exceed 1000.
# The integers in the given array are in the range of [0, 1000].# Time: O(n^2)
# Space: O(1)
class Solution(object):
def triangleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
result = 0
nums.sort()
for i in xrange(len(nums)-2):
if nums[i] == 0:
continue
k = i+2
for j in xrange(i+1, len(nums)-1):
while k < len(nums) and nums[i] + nums[j] > nums[k]:
k += 1
result += k-j-1
return result
405
coin-change-2.py
# You are given coins of different denominations and a total amount of money.
# Write a function to compute the number of combinations that make up that amount.
# You may assume that you have infinite number of each kind of coin.
#
#
#
#
#
#
# Example 1:
#
# Input: amount = 5, coins = [1, 2, 5]
# Output: 4
# Explanation: there are four ways to make up the amount:
# 5=5
# 5=2+2+1
# 5=2+1+1+1
# 5=1+1+1+1+1
#
#
# Example 2:
#
# Input: amount = 3, coins = [2]
# Output: 0
# Explanation: the amount of 3 cannot be made up just with coins of 2.
#
#
# Example 3:
#
# Input: amount = 10, coins = [10]
# Output: 1
#
#
#
#
# Note:
#
# You can assume that
#
#
# 0 <= amount <= 5000
# 1 <= coin <= 5000
# the number of coins is less than 500
# the answer is guaranteed to fit into signed 32-bit integer# Time: O(n * m)
# Space: O(m)
class Solution(object):
def change(self, amount, coins):
"""
:type amount: int
:type coins: List[int]
:rtype: int
"""
dp = [0] * (amount+1)
dp[0] = 1
for coin in coins:
for i in xrange(coin, amount+1):
dp[i] += dp[i-coin]
406
return dp[amount]
407
subsets.py
# Given a set of distinct integers, nums, return all possible subsets (the power
# set).
#
# Note: The solution set must not contain duplicate subsets.
#
# Example:
#
# Input: nums = [1,2,3]
# Output:
# [
# [3],
# [1],
# [2],
# [1,2,3],
# [1,3],
# [2,3],
# [1,2],
# []
# ]# Time: O(n * 2^n)
# Space: O(1)
class Solution(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
result = [[]]
for i in xrange(len(nums)):
size = len(result)
for j in xrange(size):
result.append(list(result[j]))
result[-1].append(nums[i])
return result
return result
408
# Time: O(n * 2^n)
# Space: O(1)
class Solution3(object):
def subsets(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
return self.subsetsRecu([], sorted(nums))
409
kth-smallest-element-in-a-sorted-matrix.py
# Given a n x n matrix where each of the rows and columns are sorted in
# ascending order, find the kth smallest element in the matrix.
#
#
# Note that it is the kth smallest element in the sorted order, not the kth
# distinct element.
#
#
# Example:
# matrix = [
# [ 1, 5, 9],
# [10, 11, 13],
# [12, 13, 15]
# ],
# k = 8,
#
# return 13.
#
#
#
# Note:
#
# You may assume k is always valid, 1 k n2.# Time: O(k * log(min(n, m, k))), with n x m matrix
# Space: O(min(n, m, k))
class Solution(object):
def kthSmallest(self, matrix, k):
"""
:type matrix: List[List[int]]
:type k: int
:rtype: int
"""
kth_smallest = 0
min_heap = []
push(0, 0)
while min_heap and k > 0:
kth_smallest, i, j = heappop(min_heap)
push(i, j + 1)
if j == 0:
push(i + 1, 0)
k -= 1
return kth_smallest
410
word-ladder.py
# Given two words (beginWord and endWord), and a dictionary's word list, find
# the length of shortest transformation sequence from beginWord to endWord, such
# that:
#
#
# Only one letter can be changed at a time.
# Each transformed word must exist in the word list.
#
#
# Note:
#
#
# Return 0 if there is no such transformation sequence.
# All words have the same length.
# All words contain only lowercase alphabetic characters.
# You may assume no duplicates in the word list.
# You may assume beginWord and endWord are non-empty and are not the same.
#
#
# Example 1:
#
# Input:
# beginWord = "hit",
# endWord = "cog",
# wordList = ["hot","dot","dog","lot","log","cog"]
#
# Output: 5
#
# Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" ->
# "dog" -> "cog",
# return its length 5.
#
#
# Example 2:
#
# Input:
# beginWord = "hit"
# endWord = "cog"
# wordList = ["hot","dot","dog","lot","log"]
#
# Output: 0
#
# Explanation: The endWord "cog" is not in wordList, therefore no
# possible transformation.# Time: O(n * d), n is length of string, d is size of dictionary
# Space: O(d)
from string import ascii_lowercase
class Solution(object):
def ladderLength(self, beginWord, endWord, wordList):
"""
:type beginWord: str
:type endWord: str
:type wordList: List[str]
:rtype: int
"""
distance, cur, visited, lookup = 0, [beginWord], set([beginWord]), set(wordList)
411
while cur:
next_queue = []
return 0
412
camelcase-matching.py
# A query word matches a given pattern if we can insert lowercase letters to the
# pattern word so that it equals the query. (We may insert each character at any
# position, and may insert 0 characters.)
#
# Given a list of queries, and a pattern, return an answer list of booleans,
# where answer[i] is true if and only if queries[i] matches the pattern.
#
#
#
# Example 1:
#
# Input: queries =
# ["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"], pattern = "FB"
# Output: [true,false,true,true,false]
# Explanation:
# "FooBar" can be generated like this "F" + "oo" + "B" + "ar".
# "FootBall" can be generated like this "F" + "oot" + "B" + "all".
# "FrameBuffer" can be generated like this "F" + "rame" + "B" + "uffer".
#
# Example 2:
#
# Input: queries =
# ["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"], pattern =
# "FoBa"
# Output: [true,false,true,false,false]
# Explanation:
# "FooBar" can be generated like this "Fo" + "o" + "Ba" + "r".
# "FootBall" can be generated like this "Fo" + "ot" + "Ba" + "ll".
#
#
# Example 3:
#
# Input: queries =
# ["FooBar","FooBarTest","FootBall","FrameBuffer","ForceFeedBack"], pattern =
# "FoBaT"
# Output: [false,true,false,false,false]
# Explanation:
# "FooBarTest" can be generated like this "Fo" + "o" + "Ba" + "r" + "T" + "est".
#
#
#
#
# Note:
#
#
# 1 <= queries.length <= 100
# 1 <= queries[i].length <= 100
# 1 <= pattern.length <= 100
# All strings consists only of lower and upper case English letters.# Time: O(n * l), n is number of qur
# , l is length of query
# Space: O(1)
class Solution(object):
def camelMatch(self, queries, pattern):
"""
:type queries: List[str]
:type pattern: str
:rtype: List[bool]
413
"""
def is_matched(query, pattern):
i = 0
for c in query:
if i < len(pattern) and pattern[i] == c:
i += 1
elif c.isupper():
return False
return i == len(pattern)
result = []
for query in queries:
result.append(is_matched(query, pattern))
return result
414
encode-and-decode-tinyurl.py
# Note: This is a companion problem to the System Design problem: Design
# TinyURL.
#
# TinyURL is a URL shortening service where you enter a URL such as
# https://leetcode.com/problems/design-tinyurl and it returns a short URL such as
# http://tinyurl.com/4e9iAk.
#
# Design the encode and decode methods for the TinyURL service. There is no
# restriction on how your encode/decode algorithm should work. You just need to
# ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded
# to the original URL.# Time: O(1)
# Space: O(n)
import random
class Codec(object):
def __init__(self):
self.__random_length = 6
self.__tiny_url = "http://tinyurl.com/"
self.__alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
self.__lookup = {}
key = getRand()
while key in self.__lookup:
key = getRand()
self.__lookup[key] = longUrl
return self.__tiny_url + key
class Codec2(object):
def __init__(self):
self._cache = {}
self.url = 'http://tinyurl.com/'
415
def encode(self, long_url):
"""Encodes a URL to a shortened URL.
416
triangle.py
# Given a triangle, find the minimum path sum from top to bottom. Each step you
# may move to adjacent numbers on the row below.
#
# For example, given the following triangle
#
# [
# [2],
# [3,4],
# [6,5,7],
# [4,1,8,3]
# ]
#
#
# The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
#
# Note:
#
# Bonus point if you are able to do this using only O(n) extra space, where n is
# the total number of rows in the triangle.from functools import reduce
# Time: O(m * n)
# Space: O(n)
class Solution(object):
# @param triangle, a list of lists of integers
# @return an integer
def minimumTotal(self, triangle):
if not triangle:
return 0
417
get-equal-substrings-within-budget.py
# You are given two strings s and t of the same length. You want to change s to
# t. Changing the i-th character of s to i-th character of t costs |s[i] - t[i]|
# that is, the absolute difference between the ASCII values of the characters.
#
# You are also given an integer maxCost.
#
# Return the maximum length of a substring of s that can be changed to be the
# same as the corresponding substring of twith a cost less than or equal to
# maxCost.
#
# If there is no substring from s that can be changed to its corresponding
# substring from t, return 0.
#
#
# Example 1:
#
# Input: s = "abcd", t = "bcdf", maxCost = 3
# Output: 3
# Explanation: "abc" of s can change to "bcd". That costs 3, so the maximum
# length is 3.
#
# Example 2:
#
# Input: s = "abcd", t = "cdef", maxCost = 3
# Output: 1
# Explanation: Each character in s costs 2 to change to charactor in t, so the
# maximum length is 1.
#
#
# Example 3:
#
# Input: s = "abcd", t = "acde", maxCost = 0
# Output: 1
# Explanation: You can't make any change, so the maximum length is 1.
#
#
#
# Constraints:
#
#
# 1 <= s.length, t.length <= 10^5
# 0 <= maxCost <= 10^6
# s and t only contain lower case English letters.# Time: O(n)
# Space: O(1)
class Solution(object):
def equalSubstring(self, s, t, maxCost):
"""
:type s: str
:type t: str
:type maxCost: int
:rtype: int
"""
left = 0
for right in xrange(len(s)):
maxCost -= abs(ord(s[right])-ord(t[right]))
if maxCost < 0:
maxCost += abs(ord(s[left])-ord(t[left]))
418
left += 1
return (right+1)-left
419
score-after-flipping-matrix.py
# We have a two dimensional matrix A where each value is 0 or 1.
#
# A move consists of choosing any row or column, and toggling each value in that
# row or column: changing all 0s to 1s, and all 1s to 0s.
#
# After making any number of moves, every row of this matrix is interpreted as a
# binary number, and the score of the matrix is the sum of these numbers.
#
# Return the highest possible score.
#
#
#
#
#
#
#
# Example 1:
#
# Input: [[0,0,1,1],[1,0,1,0],[1,1,0,0]]
# Output: 39
# Explanation:
# Toggled to [[1,1,1,1],[1,0,0,1],[1,1,1,1]].
# 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39
#
#
#
# Note:
#
#
# 1 <= A.length <= 20
# 1 <= A[0].length <= 20
# A[i][j] is 0 or 1.# Time: O(r * c)
# Space: O(1)
class Solution(object):
def matrixScore(self, A):
"""
:type A: List[List[int]]
:rtype: int
"""
R, C = len(A), len(A[0])
result = 0
for c in xrange(C):
col = 0
for r in xrange(R):
col += A[r][c] ^ A[r][0]
result += max(col, R-col) * 2**(C-1-c)
return result
420
subarray-sums-divisible-by-k.py
# Given an array A of integers, return the number of (contiguous, non-empty)
# subarrays that have a sum divisible by K.
#
#
#
#
# Example 1:
#
# Input: A = [4,5,0,-2,-3,1], K = 5
# Output: 7
# Explanation: There are 7 subarrays with a sum divisible by K = 5:
# [4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
#
#
#
#
# Note:
#
#
# 1 <= A.length <= 30000
# -10000 <= A[i] <= 10000
# 2 <= K <= 10000# Time: O(n)
# Space: O(k)
import collections
class Solution(object):
def subarraysDivByK(self, A, K):
"""
:type A: List[int]
:type K: int
:rtype: int
"""
count = collections.defaultdict(int)
count[0] = 1
result, prefix = 0, 0
for a in A:
prefix = (prefix+a) % K
result += count[prefix]
count[prefix] += 1
return result
421
lowest-common-ancestor-of-deepest-leaves.py
# Given a rooted binary tree, return the lowest common ancestor of its deepest
# leaves.
#
# Recall that:
#
#
# The node of a binary tree is a leaf if and only if it has no children
# The depth of the root of the tree is 0, and if the depth of a node is d,
# the depth of each of its children is d+1.
# The lowest common ancestor of a set S of nodes is the node A with the
# largest depth such that every node in S is in the subtree with root A.
#
#
#
# Example 1:
#
# Input: root = [1,2,3]
# Output: [1,2,3]
# Explanation:
# The deepest leaves are the nodes with values 2 and 3.
# The lowest common ancestor of these leaves is the node with value 1.
# The answer returned is a TreeNode object (not an array) with serialization
# "[1,2,3]".
#
#
# Example 2:
#
# Input: root = [1,2,3,4]
# Output: [4]
#
#
# Example 3:
#
# Input: root = [1,2,3,4,5]
# Output: [2,4,5]
#
#
#
# Constraints:
#
#
# The given tree will have between 1 and 1000 nodes.
# Each node of the tree will have a distinct value between 1 and 1000.# Time: O(n)
# Space: O(h)
class Solution(object):
def lcaDeepestLeaves(self, root):
"""
:type root: TreeNode
:rtype: TreeNode
422
"""
def lcaDeepestLeavesHelper(root):
if not root:
return 0, None
d1, lca1 = lcaDeepestLeavesHelper(root.left)
d2, lca2 = lcaDeepestLeavesHelper(root.right)
if d1 > d2:
return d1+1, lca1
if d1 < d2:
return d2+1, lca2
return d1+1, root
return lcaDeepestLeavesHelper(root)[1]
423
3sum-with-multiplicity.py
# Given an integer array A, and an integer target, return the number
# of tuples i, j, k such that i < j < k and A[i] + A[j] + A[k] == target.
#
# As the answer can be very large, return it modulo 109 + 7.
#
#
# Example 1:
#
# Input: A = [1,1,2,2,3,3,4,4,5,5], target = 8
# Output: 20
# Explanation:
# Enumerating by the values (A[i], A[j], A[k]):
# (1, 2, 5) occurs 8 times;
# (1, 3, 4) occurs 8 times;
# (2, 2, 4) occurs 2 times;
# (2, 3, 3) occurs 2 times.
#
#
# Example 2:
#
# Input: A = [1,1,2,2,2,2], target = 5
# Output: 12
# Explanation:
# A[i] = 1, A[j] = A[k] = 2 occurs 12 times:
# We choose one 1 from [1,1] in 2 ways,
# and two 2s from [2,2,2,2] in 6 ways.
#
#
#
# Constraints:
#
#
# 3 <= A.length <= 3000
# 0 <= A[i] <= 100
# 0 <= target <= 300# Time: O(n^2), n is the number of disctinct A[i]
# Space: O(n)
import collections
import itertools
class Solution(object):
def threeSumMulti(self, A, target):
"""
:type A: List[int]
:type target: int
:rtype: int
"""
count = collections.Counter(A)
result = 0
for i, j in itertools.combinations_with_replacement(count, 2):
k = target - i - j
if i == j == k:
result += count[i] * (count[i]-1) * (count[i]-2) // 6
elif i == j != k:
result += count[i] * (count[i]-1) // 2 * count[k]
elif max(i, j) < k:
result += count[i] * count[j] * count[k]
424
return result % (10**9 + 7)
425
max-consecutive-ones-iii.py
# Given an array A of 0s and 1s, we may change up to K values from 0 to 1.
#
# Return the length of the longest (contiguous) subarray that contains only 1s.
#
#
#
#
# Example 1:
#
# Input: A = [1,1,1,0,0,0,1,1,1,1,0], K = 2
# Output: 6
# Explanation:
# [1,1,1,0,0,1,1,1,1,1,1]
# Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.
#
#
# Example 2:
#
# Input: A = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
# Output: 10
# Explanation:
# [0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
# Bolded numbers were flipped from 0 to 1. The longest subarray is underlined.
#
#
#
#
# Note:
#
#
# 1 <= A.length <= 20000
# 0 <= K <= A.length
# A[i] is 0 or 1# Time: O(n)
# Space: O(1)
class Solution(object):
def longestOnes(self, A, K):
"""
:type A: List[int]
:type K: int
:rtype: int
"""
result, i = 0, 0
for j in xrange(len(A)):
K -= int(A[j] == 0)
while K < 0:
K += int(A[i] == 0)
i += 1
result = max(result, j-i+1)
return result
426
adding-two-negabinary-numbers.py
# Given two numbers arr1 and arr2 in base -2, return the result of adding them
# together.
#
# Each number is given in array format: as an array of 0s and 1s, from most
# significant bit to least significant bit. For example, arr = [1,1,0,1]
# represents the number (-2)^3 + (-2)^2 + (-2)^0 = -3. A number arr in array
# format is also guaranteed to have no leading zeros: either arr == [0] or arr[0]
# == 1.
#
# Return the result of adding arr1 and arr2 in the same format: as an array of
# 0s and 1s with no leading zeros.
#
#
#
# Example 1:
#
# Input: arr1 = [1,1,1,1,1], arr2 = [1,0,1]
# Output: [1,0,0,0,0]
# Explanation: arr1 represents 11, arr2 represents 5, the output represents 16.
#
#
#
#
# Note:
#
#
# 1 <= arr1.length <= 1000
# 1 <= arr2.length <= 1000
# arr1 and arr2 have no leading zeros
# arr1[i] is 0 or 1
# arr2[i] is 0 or 1# Time: O(n)
# Space: O(n)
class Solution(object):
def addNegabinary(self, arr1, arr2):
"""
:type arr1: List[int]
:type arr2: List[int]
:rtype: List[int]
"""
result = []
carry = 0
while arr1 or arr2 or carry:
if arr1:
carry += arr1.pop()
if arr2:
carry += arr2.pop()
result.append(carry & 1)
carry = -(carry >> 1)
while len(result) > 1 and result[-1] == 0:
result.pop()
result.reverse()
return result
427
map-sum-pairs.py
# Implement a MapSum class with insert, and sum methods.
#
#
#
# For the method insert, you'll be given a pair of (string, integer). The string
# represents the key and the integer represents the value. If the key already
# existed, then the original key-value pair will be overridden to the new one.
#
#
#
# For the method sum, you'll be given a string representing the prefix, and you
# need to return the sum of all the pairs' value whose key starts with the prefix.
#
#
# Example 1:
#
# Input: insert("apple", 3), Output: Null
# Input: sum("ap"), Output: 3
# Input: insert("app", 2), Output: Null
# Input: sum("ap"), Output: 5# Time: O(n), n is the length of key
# Space: O(t), t is the number of nodes in trie
import collections
class MapSum(object):
def __init__(self):
"""
Initialize your data structure here.
"""
_trie = lambda: collections.defaultdict(_trie)
self.__root = _trie()
curr = self.__root
for c in key:
curr = curr[c]
if "_count" in curr:
curr["_count"] += delta
else:
curr["_count"] = delta
curr["_end"] = val
428
def sum(self, prefix):
"""
:type prefix: str
:rtype: int
"""
# Time: O(n)
curr = self.__root
for c in prefix:
if c not in curr:
return 0
curr = curr[c]
return curr["_count"]
429
binary-tree-coloring-game.py
# Two players play a turn based game on a binary tree. We are given the root of
# this binary tree, and the number of nodes n in the tree. n is odd, and each
# node has a distinct value from 1 to n.
#
# Initially, the first player names a value x with 1 <= x <= n, and the second
# player names a value y with 1 <= y <= n and y != x. The first player colors the
# node with value x red, and the second player colors the node with value y blue.
#
# Then, the players take turns starting with the first player. In each turn,
# that player chooses a node of their color (red if player 1, blue if player 2)
# and colors an uncolored neighbor of the chosen node (either the left child,
# right child, or parent of the chosen node.)
#
# If (and only if) a player cannot choose such a node in this way, they must
# pass their turn. If both players pass their turn, the game ends, and the winner
# is the player that colored more nodes.
#
# You are the second player. If it is possible to choose such a y to ensure you
# win the game, return true. If it is not possible, return false.
#
#
# Example 1:
#
# Input: root = [1,2,3,4,5,6,7,8,9,10,11], n = 11, x = 3
# Output: true
# Explanation: The second player can choose the node with value 2.
#
#
#
# Constraints:
#
#
# root is the root of a binary tree with n nodes and distinct node values
# from 1 to n.
# n is odd.
# 1 <= x <= n <= 100# Time: O(n)
# Space: O(h)
class Solution(object):
def btreeGameWinningMove(self, root, n, x):
"""
:type root: TreeNode
:type n: int
:type x: int
:rtype: bool
"""
def count(node, x, left_right):
if not node:
return 0
left, right = count(node.left, x, left_right), count(node.right, x, left_right)
430
if node.val == x:
left_right[0], left_right[1] = left, right
return left + right + 1
left_right = [0, 0]
count(root, x, left_right)
blue = max(max(left_right), n-(sum(left_right)+1))
return blue > n-blue
431
non-overlapping-intervals.py
# Given a collection of intervals, find the minimum number of intervals you need
# to remove to make the rest of the intervals non-overlapping.
#
#
#
#
#
#
# Example 1:
#
# Input: [[1,2],[2,3],[3,4],[1,3]]
# Output: 1
# Explanation: [1,3] can be removed and the rest of intervals are non-
# overlapping.
#
#
# Example 2:
#
# Input: [[1,2],[1,2],[1,2]]
# Output: 2
# Explanation: You need to remove two [1,2] to make the rest of intervals non-
# overlapping.
#
#
# Example 3:
#
# Input: [[1,2],[2,3]]
# Output: 0
# Explanation: You don't need to remove any of the intervals since they're
# already non-overlapping.
#
#
#
#
# Note:
#
#
# You may assume the interval's end point is always bigger than its start
# point.
# Intervals like [1,2] and [2,3] have borders "touching" but they don't
# overlap each other.# Time: O(nlogn)
# Space: O(1)
class Solution(object):
def eraseOverlapIntervals(self, intervals):
"""
:type intervals: List[Interval]
:rtype: int
"""
intervals.sort(key=lambda interval: interval.start)
result, prev = 0, 0
for i in xrange(1, len(intervals)):
if intervals[i].start < intervals[prev].end:
if intervals[i].end < intervals[prev].end:
prev = i
result += 1
else:
prev = i
432
return result
433
reverse-substrings-between-each-pair-of-parentheses.py
# You are given a string s that consists of lower case English letters and
# brackets.
#
# Reverse the strings in each pair of matching parentheses, starting from the
# innermost one.
#
# Your result should not contain any brackets.
#
#
# Example 1:
#
# Input: s = "(abcd)"
# Output: "dcba"
#
#
# Example 2:
#
# Input: s = "(u(love)i)"
# Output: "iloveu"
# Explanation: The substring "love" is reversed first, then the whole string is
# reversed.
#
#
# Example 3:
#
# Input: s = "(ed(et(oc))el)"
# Output: "leetcode"
# Explanation: First, we reverse the substring "oc", then "etco", and finally,
# the whole string.
#
#
# Example 4:
#
# Input: s = "a(bcdefghijkl(mno)p)q"
# Output: "apmnolkjihgfedcbq"
#
#
#
# Constraints:
#
#
# 0 <= s.length <= 2000
# s only contains lower case English characters and parentheses.
# It's guaranteed that all parentheses are balanced.# Time: O(n)
# Space: O(n)
class Solution(object):
def reverseParentheses(self, s):
"""
:type s: str
:rtype: str
"""
stk, lookup = [], {}
for i, c in enumerate(s):
if c == '(':
stk.append(i)
elif c == ')':
j = stk.pop()
434
lookup[i], lookup[j] = j, i
result = []
i, d = 0, 1
while i < len(s):
if i in lookup:
i = lookup[i]
d *= -1
else:
result.append(s[i])
i += d
return "".join(result)
# Time: O(n^2)
# Space: O(n)
class Solution2(object):
def reverseParentheses(self, s):
"""
:type s: str
:rtype: str
"""
stk = [[]]
for c in s:
if c == '(':
stk.append([])
elif c == ')':
end = stk.pop()
end.reverse()
stk[-1].extend(end)
else:
stk[-1].append(c)
return "".join(stk.pop())
435
restore-ip-addresses.py
# Given a string s containing only digits. Return all possible valid IP
# addresses that can be obtained from s. You can return them in any order.
#
# A valid IP address consists of exactly four integers, each integer is between
# 0 and 255, separated by single points and cannot have leading zeros. For
# example, "0.1.2.201" and "192.168.1.1" are valid IP addresses and
# "0.011.255.245", "192.168.1.312" and "[email protected]" are invalid IP addresses.
#
#
# Example 1:
# Input: s = "25525511135"
# Output: ["255.255.11.135","255.255.111.35"]
# Example 2:
# Input: s = "0000"
# Output: ["0.0.0.0"]
# Example 3:
# Input: s = "1111"
# Output: ["1.1.1.1"]
# Example 4:
# Input: s = "010010"
# Output: ["0.10.0.10","0.100.1.0"]
# Example 5:
# Input: s = "101023"
# Output: ["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
#
#
# Constraints:
#
#
# 0 <= s.length <= 3000
# s consists of digits only.# Time: O(n^m) = O(3^4)
# Space: O(n * m) = O(3 * 4)
class Solution(object):
# @param s, a string
# @return a list of strings
def restoreIpAddresses(self, s):
result = []
self.restoreIpAddressesRecur(result, s, 0, "", 0)
return result
436
return int(s) < 256
437
random-point-in-non-overlapping-rectangles.py
# Example 1:
#
# Input:
# ["Solution","pick","pick","pick"]
# [[[[1,1,5,5]]],[],[],[]]
# Output:
# [null,[4,1],[4,1],[3,3]]
#
#
#
# Example 2:
#
# Input:
# ["Solution","pick","pick","pick","pick","pick"]
# [[[[-2,-2,-1,-1],[1,0,3,0]]],[],[],[],[],[]]
# Output:
# [null,[-1,-2],[2,0],[-2,-1],[3,0],[-2,-2]]
#
#
#
# Explanation of Input Syntax:
#
# The input is two lists: the subroutines called and
# their arguments. Solution's constructor has one argument, the array of
# rectangles rects. pick has no arguments. Arguments are always wrapped with a
# list, even if there aren't any.# Time: ctor: O(n)
# pick: O(logn)
# Space: O(n)
import random
import bisect
class Solution(object):
def pick(self):
"""
:rtype: List[int]
"""
target = random.randint(0, self.__prefix_sum[-1]-1)
left = bisect.bisect_right(self.__prefix_sum, target)
rect = self.__rects[left]
width, height = rect[2]-rect[0]+1, rect[3]-rect[1]+1
base = self.__prefix_sum[left]-width*height
return [rect[0]+(target-base)%width, rect[1]+(target-base)//width]
438
super-ugly-number.py
# Write a program to find the nth super ugly number.
#
# Super ugly numbers are positive numbers whose all prime factors are in the
# given prime list primes of size k.
#
# Example:
#
# Input: n = 12, primes = [2,7,13,19]
# Output: 32
# Explanation: [1,2,4,7,8,13,14,16,19,26,28,32] is the sequence of the first 12
# super ugly numbers given primes = [2,7,13,19] of size 4.
#
# Note:
#
#
# 1 is a super ugly number for any given primes.
# The given numbers in primes are in ascending order.
# 0 < k 100, 0 < n 106, 0 < primes[i] < 1000.
# The nth super ugly number is guaranteed to fit in a 32-bit signed
# integer.# Time: O(n * k)
# Space: O(n + k)
import heapq
for k, p in enumerate(primes):
heapq.heappush(heap, (p, k))
return uglies[-1]
# Time: O(n * k)
# Space: O(n + k)
# Hash solution. (932ms)
class Solution2(object):
def nthSuperUglyNumber(self, n, primes):
"""
:type n: int
:type primes: List[int]
:rtype: int
439
"""
uglies, idx, heap, ugly_set = [0] * n, [0] * len(primes), [], set([1])
uglies[0] = 1
for k, p in enumerate(primes):
heapq.heappush(heap, (p, k))
ugly_set.add(p)
return uglies[-1]
return uglies[-1]
# Time: O(n * k)
# Space: O(n + k)
# TLE due to the last test case, but it passess and performs the best in C++.
class Solution4(object):
def nthSuperUglyNumber(self, n, primes):
"""
:type n: int
:type primes: List[int]
:rtype: int
"""
uglies = [0] * n
uglies[0] = 1
ugly_by_prime = list(primes)
idx = [0] * len(primes)
440
idx[k] += 1
ugly_by_prime[k] = primes[k] * uglies[idx[k]]
return uglies[-1]
heap = []
heapq.heappush(heap, 1)
for p in primes:
heapq.heappush(heap, p)
for _ in xrange(n):
ugly_number = heapq.heappop(heap)
for i in xrange(len(primes)):
if ugly_number % primes[i] == 0:
for j in xrange(i + 1):
heapq.heappush(heap, ugly_number * primes[j])
break
return ugly_number
441
minimum-increment-to-make-array-unique.py
# Given an array of integers A, a move consists of choosing any A[i], and
# incrementing it by 1.
#
# Return the least number of moves to make every value in A unique.
#
#
#
# Example 1:
#
# Input: [1,2,2]
# Output: 1
# Explanation: After 1 move, the array could be [1, 2, 3].
#
#
#
# Example 2:
#
# Input: [3,2,1,2,1,7]
# Output: 6
# Explanation: After 6 moves, the array could be [3, 4, 1, 2, 5, 7].
# It can be shown with 5 or less moves that it is impossible for the array to
# have all unique values.
#
#
#
#
#
# Note:
#
#
# 0 <= A.length <= 40000
# 0 <= A[i] < 40000# Time: O(nlogn)
# Space: O(n)
class Solution(object):
def minIncrementForUnique(self, A):
"""
:type A: List[int]
:rtype: int
"""
A.sort()
A.append(float("inf"))
result, duplicate = 0, 0
for i in xrange(1, len(A)):
if A[i-1] == A[i]:
duplicate += 1
result -= A[i]
else:
move = min(duplicate, A[i]-A[i-1]-1)
duplicate -= move
result += move*A[i-1] + move*(move+1)//2
return result
442
find-right-interval.py
# Given a set of intervals, for each of the interval i, check if there exists an
# interval j whose start point is bigger than or equal to the end point of the
# interval i, which can be called that j is on the "right" of i.
#
# For any interval i, you need to store the minimum interval j's index, which
# means that the interval j has the minimum start point to build the "right"
# relationship for interval i. If the interval j doesn't exist, store -1 for the
# interval i. Finally, you need output the stored value of each interval as an
# array.
#
# Note:
#
#
# You may assume the interval's end point is always bigger than its start
# point.
# You may assume none of these intervals have the same start point.
#
#
#
#
# Example 1:
#
# Input: [ [1,2] ]
#
# Output: [-1]
#
# Explanation: There is only one interval in the collection, so it outputs -1.
#
#
#
#
# Example 2:
#
# Input: [ [3,4], [2,3], [1,2] ]
#
# Output: [-1, 0, 1]
#
# Explanation: There is no satisfied "right" interval for [3,4].
# For [2,3], the interval [3,4] has minimum-"right" start point;
# For [1,2], the interval [2,3] has minimum-"right" start point.
#
#
#
#
# Example 3:
#
# Input: [ [1,4], [2,3], [3,4] ]
#
# Output: [-1, 2, -1]
#
# Explanation: There is no satisfied "right" interval for [1,4] and [3,4].
# For [2,3], the interval [3,4] has minimum-"right" start point.
#
#
# NOTE: input types have been changed on April 15, 2019. Please reset to default
# code definition to get new method signature.# Time: O(nlogn)
# Space: O(n)
443
import bisect
class Solution(object):
def findRightInterval(self, intervals):
"""
:type intervals: List[Interval]
:rtype: List[int]
"""
sorted_intervals = sorted((interval.start, i) for i, interval in enumerate(intervals))
result = []
for interval in intervals:
idx = bisect.bisect_left(sorted_intervals, (interval.end,))
result.append(sorted_intervals[idx][1] if idx < len(sorted_intervals) else -1)
return result
444
longest-happy-string.py
# A string is called happy if it does not have any of the strings 'aaa',
# 'bbb' or 'ccc' as a substring.
#
# Given three integers a, b and c, return any string s, which satisfies
# following conditions:
#
#
# s is happy and longest possible.
# s contains at most a occurrences of the letter 'a', at most
# b occurrences of the letter 'b' and at most c occurrences of the letter 'c'.
# s will only contain 'a', 'b' and 'c' letters.
#
#
# If there is no such string s return the empty string "".
#
#
# Example 1:
#
# Input: a = 1, b = 1, c = 7
# Output: "ccaccbcc"
# Explanation: "ccbccacc" would also be a correct answer.
#
#
# Example 2:
#
# Input: a = 2, b = 2, c = 1
# Output: "aabbc"
#
#
# Example 3:
#
# Input: a = 7, b = 1, c = 0
# Output: "aabaa"
# Explanation: It's the only correct answer in this case.
#
#
#
# Constraints:
#
#
# 0 <= a, b, c <= 100
# a + b + c > 0# Time: O(n)
# Space: O(1)
import heapq
class Solution(object):
def longestDiverseString(self, a, b, c):
"""
:type a: int
:type b: int
:type c: int
:rtype: str
"""
max_heap = []
if a:
heapq.heappush(max_heap, (-a, 'a'))
445
if b:
heapq.heappush(max_heap, (-b, 'b'))
if c:
heapq.heappush(max_heap, (-c, 'c'))
result = []
while max_heap:
count1, c1 = heapq.heappop(max_heap)
if len(result) >= 2 and result[-1] == result[-2] == c1:
if not max_heap:
return "".join(result)
count2, c2 = heapq.heappop(max_heap)
result.append(c2)
count2 += 1
if count2:
heapq.heappush(max_heap, (count2, c2))
heapq.heappush(max_heap, (count1, c1))
continue
result.append(c1)
count1 += 1
if count1 != 0:
heapq.heappush(max_heap, (count1, c1))
return "".join(result)
# Time: O(n)
# Space: O(1)
class Solution2(object):
def longestDiverseString(self, a, b, c):
"""
:type a: int
:type b: int
:type c: int
:rtype: str
"""
choices = [[a, 'a'], [b, 'b'], [c, 'c']]
result = []
for _ in xrange(a+b+c):
choices.sort(reverse=True)
for i, (x, c) in enumerate(choices):
if x and result[-2:] != [c, c]:
result.append(c)
choices[i][0] -= 1
break
else:
break
return "".join(result)
446
generate-parentheses.py
# Given n pairs of parentheses, write a function to generate all combinations of
# well-formed parentheses.
#
#
#
# For example, given n = 3, a solution set is:
#
# [
# "((()))",
# "(()())",
# "(())()",
# "()(())",
# "()()()"
# ]# Time: O(4^n / n^(3/2)) ~= Catalan numbers
# Space: O(n)
class Solution(object):
# @param an integer
# @return a list of string
def generateParenthesis(self, n):
result = []
self.generateParenthesisRecu(result, "", n, n)
return result
447
target-sum.py
# You are given a list of non-negative integers, a1, a2, ..., an, and a target,
# S. Now you have 2 symbols + and -. For each integer, you should choose one from
# + and - as its new symbol.
#
# Find out how many ways to assign symbols to make sum of integers equal to
# target S.
#
# Example 1:
#
# Input: nums is [1, 1, 1, 1, 1], S is 3.
# Output: 5
# Explanation:
#
# -1+1+1+1+1 = 3
# +1-1+1+1+1 = 3
# +1+1-1+1+1 = 3
# +1+1+1-1+1 = 3
# +1+1+1+1-1 = 3
#
# There are 5 ways to assign symbols to make the sum of nums be target 3.
#
#
#
# Constraints:
#
#
# The length of the given array is positive and will not exceed 20.
# The sum of elements in the given array will not exceed 1000.
# Your output answer is guaranteed to be fitted in a 32-bit integer.# Time: O(n * S)
# Space: O(S)
import collections
class Solution(object):
def findTargetSumWays(self, nums, S):
"""
:type nums: List[int]
:type S: int
:rtype: int
"""
def subsetSum(nums, S):
dp = collections.defaultdict(int)
dp[0] = 1
for n in nums:
for i in reversed(xrange(n, S+1)):
if i-n in dp:
dp[i] += dp[i-n]
return dp[S]
total = sum(nums)
if total < S or (S + total) % 2: return 0
P = (S + total) // 2
return subsetSum(nums, P)
448
permutation-in-string.py
# Given two strings s1 and s2, write a function to return true if s2 contains
# the permutation of s1. In other words, one of the first string's permutations is
# the substring of the second string.
#
#
#
# Example 1:
#
# Input: s1 = "ab" s2 = "eidbaooo"
# Output: True
# Explanation: s2 contains one permutation of s1 ("ba").
#
#
# Example 2:
#
# Input:s1= "ab" s2 = "eidboaoo"
# Output: False
#
#
#
# Constraints:
#
#
# The input strings only contain lower case letters.
# The length of both given strings is in range [1, 10,000].# Time: O(n)
# Space: O(1)
import collections
class Solution(object):
def checkInclusion(self, s1, s2):
"""
:type s1: str
:type s2: str
:rtype: bool
"""
counts = collections.Counter(s1)
l = len(s1)
for i in xrange(len(s2)):
if counts[s2[i]] > 0:
l -= 1
counts[s2[i]] -= 1
if l == 0:
return True
start = i + 1 - len(s1)
if start >= 0:
counts[s2[start]] += 1
if counts[s2[start]] > 0:
l += 1
return False
449
maximum-swap.py
# Given a non-negative integer, you could swap two digits at most once to get
# the maximum valued number. Return the maximum valued number you could get.
#
#
# Example 1:
#
# Input: 2736
# Output: 7236
# Explanation: Swap the number 2 and the number 7.
#
#
#
# Example 2:
#
# Input: 9973
# Output: 9973
# Explanation: No swap.
#
#
#
#
# Note:
#
#
# The given number is in the range [0, 108]# Time: O(logn), logn is the length of the number string
# Space: O(logn)
class Solution(object):
def maximumSwap(self, num):
"""
:type num: int
:rtype: int
"""
digits = list(str(num))
left, right = 0, 0
max_idx = len(digits)-1
for i in reversed(xrange(len(digits))):
if digits[i] > digits[max_idx]:
max_idx = i
elif digits[max_idx] > digits[i]:
left, right = i, max_idx
digits[left], digits[right] = digits[right], digits[left]
return int("".join(digits))
450
best-time-to-buy-and-sell-stock-with-cooldown.py
# Say you have an array for which the ith element is the price of a given stock
# on day i.
#
# Design an algorithm to find the maximum profit. You may complete as many
# transactions as you like (ie, buy one and sell one share of the stock multiple
# times) with the following restrictions:
#
#
# You may not engage in multiple transactions at the same time (ie, you
# must sell the stock before you buy again).
# After you sell your stock, you cannot buy stock on next day. (ie,
# cooldown 1 day)
#
#
# Example:
#
# Input: [1,2,3,0,2]
# Output: 3
# Explanation: transactions = [buy, sell, cooldown, buy, sell]# Time: O(n)
# Space: O(1)
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if not prices:
return 0
buy, sell, coolDown = [0] * 2, [0] * 2, [0] * 2
buy[0] = -prices[0]
for i in xrange(1, len(prices)):
# Bought before or buy today.
buy[i % 2] = max(buy[(i - 1) % 2],
coolDown[(i - 1) % 2] - prices[i])
# Sell today.
sell[i % 2] = buy[(i - 1) % 2] + prices[i]
# Sold before yesterday or sold yesterday.
coolDown[i % 2] = max(coolDown[(i - 1) % 2], sell[(i - 1) % 2])
return max(coolDown[(len(prices) - 1) % 2],
sell[(len(prices) - 1) % 2])
451
simplify-path.py
# Given an absolute path for a file (Unix-style), simplify it. Or in other
# words, convert it to the canonical path.
#
# In a UNIX-style file system, a period . refers to the current directory.
# Furthermore, a double period .. moves the directory up a level.
#
# Note that the returned canonical path must always begin with a slash /, and
# there must be only a single slash / between two directory names. The last
# directory name (if it exists) must not end with a trailing /. Also, the
# canonical path must be the shortest string representing the absolute path.
#
#
#
# Example 1:
#
# Input: "/home/"
# Output: "/home"
# Explanation: Note that there is no trailing slash after the last directory
# name.
#
#
# Example 2:
#
# Input: "/../"
# Output: "/"
# Explanation: Going one level up from the root directory is a no-op, as the
# root level is the highest level you can go.
#
#
# Example 3:
#
# Input: "/home//foo/"
# Output: "/home/foo"
# Explanation: In the canonical path, multiple consecutive slashes are replaced
# by a single one.
#
#
# Example 4:
#
# Input: "/a/./b/../../c/"
# Output: "/c"
#
#
# Example 5:
#
# Input: "/a/../../b/../c//.//"
# Output: "/c"
#
#
# Example 6:
#
# Input: "/a//b////c/d//././/.."
# Output: "/a/b/c"# Time: O(n)
# Space: O(n)
class Solution(object):
# @param path, a string
# @return a string
452
def simplifyPath(self, path):
stack, tokens = [], path.split("/")
for token in tokens:
if token == ".." and stack:
stack.pop()
elif token != ".." and token != "." and token:
stack.append(token)
return "/" + "/".join(stack)
453
maximum-binary-tree.py
# Given an integer array with no duplicates. A maximum tree building on this
# array is defined as follow:
#
# The root is the maximum number in the array.
# The left subtree is the maximum tree constructed from left part subarray
# divided by the maximum number.
# The right subtree is the maximum tree constructed from right part subarray
# divided by the maximum number.
#
#
#
#
# Construct the maximum tree by the given array and output the root node of this
# tree.
#
#
# Example 1:
#
# Input: [3,2,1,6,0,5]
# Output: return the tree root node representing the following tree:
#
# 6
# / \
# 3 5
# \ /
# 2 0
# \
# 1
#
#
#
# Note:
#
#
# The size of the given array will be in the range [1,1000].# Time: O(n)
# Space: O(n)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def constructMaximumBinaryTree(self, nums):
"""
:type nums: List[int]
:rtype: TreeNode
"""
# https://github.com/kamyu104/LintCode/blob/master/C++/max-tree.cpp
nodeStack = []
for num in nums:
node = TreeNode(num)
while nodeStack and num > nodeStack[-1].val:
node.left = nodeStack.pop()
if nodeStack:
nodeStack[-1].right = node
454
nodeStack.append(node)
return nodeStack[0]
455
decode-string.py
# Given an encoded string, return its decoded string.
#
# The encoding rule is: k[encoded_string], where the encoded_string inside the
# square brackets is being repeated exactly k times. Note that k is guaranteed to
# be a positive integer.
#
# You may assume that the input string is always valid; No extra white spaces,
# square brackets are well-formed, etc.
#
# Furthermore, you may assume that the original data does not contain any digits
# and that digits are only for those repeat numbers, k. For example, there won't
# be input like 3a or 2[4].
#
#
# Example 1:
# Input: s = "3[a]2[bc]"
# Output: "aaabcbc"
# Example 2:
# Input: s = "3[a2[c]]"
# Output: "accaccacc"
# Example 3:
# Input: s = "2[abc]3[cd]ef"
# Output: "abcabccdcdcdef"
# Example 4:
# Input: s = "abc3[cd]xyz"
# Output: "abccdcdcdxyz"# Time: O(n)
# Space: O(n)
class Solution(object):
def decodeString(self, s):
"""
:type s: str
:rtype: str
"""
curr, nums, strs = [], [], []
n = 0
for c in s:
if c.isdigit():
n = n * 10 + ord(c) - ord('0')
elif c == '[':
nums.append(n)
n = 0
strs.append(curr)
curr = []
elif c == ']':
strs[-1].extend(curr * nums.pop())
curr = strs.pop()
else:
curr.append(c)
456
smallest-string-with-swaps.py
# You are given a string s, and an array of pairs of indices in the
# string pairs where pairs[i] = [a, b] indicates 2 indices(0-indexed) of the
# string.
#
# You can swap the characters at any pair of indices in the given pairs any
# number of times.
#
# Return the lexicographically smallest string that s can be changed to after
# using the swaps.
#
#
# Example 1:
#
# Input: s = "dcab", pairs = [[0,3],[1,2]]
# Output: "bacd"
# Explaination:
# Swap s[0] and s[3], s = "bcad"
# Swap s[1] and s[2], s = "bacd"
#
#
# Example 2:
#
# Input: s = "dcab", pairs = [[0,3],[1,2],[0,2]]
# Output: "abcd"
# Explaination:
# Swap s[0] and s[3], s = "bcad"
# Swap s[0] and s[2], s = "acbd"
# Swap s[1] and s[2], s = "abcd"
#
# Example 3:
#
# Input: s = "cba", pairs = [[0,1],[1,2]]
# Output: "abc"
# Explaination:
# Swap s[0] and s[1], s = "bca"
# Swap s[1] and s[2], s = "bac"
# Swap s[0] and s[1], s = "abc"
#
#
#
# Constraints:
#
#
# 1 <= s.length <= 10^5
# 0 <= pairs.length <= 10^5
# 0 <= pairs[i][0], pairs[i][1] < s.length
# s only contains lower case English letters.# Time: O(nlogn)
# Space: O(n)
import collections
class UnionFind(object):
def __init__(self, n):
self.set = range(n)
457
self.set[x] = self.find_set(self.set[x]) # path compression.
return self.set[x]
class Solution(object):
def smallestStringWithSwaps(self, s, pairs):
"""
:type s: str
:type pairs: List[List[int]]
:rtype: str
"""
union_find = UnionFind(len(s))
for x,y in pairs:
union_find.union_set(x, y)
components = collections.defaultdict(list)
for i in xrange(len(s)):
components[union_find.find_set(i)].append(s[i])
for i in components.iterkeys():
components[i].sort(reverse=True)
result = []
for i in xrange(len(s)):
result.append(components[union_find.find_set(i)].pop())
return "".join(result)
# Time: O(nlogn)
# Space: O(n)
import itertools
class Solution2(object):
def smallestStringWithSwaps(self, s, pairs):
"""
:type s: str
:type pairs: List[List[int]]
:rtype: str
"""
def dfs(i, adj, lookup, component):
lookup.add(i)
component.append(i)
for j in adj[i]:
if j in lookup:
continue
dfs(j, adj, lookup, component)
adj = collections.defaultdict(list)
for i, j in pairs:
adj[i].append(j)
adj[j].append(i)
lookup = set()
result = list(s)
for i in xrange(len(s)):
if i in lookup:
continue
component = []
458
dfs(i, adj, lookup, component)
component.sort()
chars = sorted(result[k] for k in component)
for comp, char in itertools.izip(component, chars):
result[comp] = char
return "".join(result)
459
optimal-division.py
# Given a list of positive integers, the adjacent integers will perform the
# float division. For example, [2,3,4] -> 2 / 3 / 4.
#
# However, you can add any number of parenthesis at any position to change the
# priority of operations. You should find out how to add parenthesis to get the
# maximum result, and return the corresponding expression in string format. Your
# expression should NOT contain redundant parenthesis.
#
# Example:
#
# Input: [1000,100,10,2]
# Output: "1000/(100/10/2)"
# Explanation:
# 1000/(100/10/2) = 1000/((100/10)/2) = 200
# However, the bold parenthesis in "1000/((100/10)/2)" are redundant,
# since they don't influence the operation priority. So you should return
# "1000/(100/10/2)".
#
# Other cases:
# 1000/(100/10)/2 = 50
# 1000/(100/(10/2)) = 50
# 1000/100/10/2 = 0.5
# 1000/100/(10/2) = 2
#
#
#
# Note:
#
# The length of the input array is [1, 10].
# Elements in the given array will be in range [2, 1000].
# There is only one optimal division for each test case.# Time: O(n)
# Space: O(1)
class Solution(object):
def optimalDivision(self, nums):
"""
:type nums: List[int]
:rtype: str
"""
if len(nums) == 1:
return str(nums[0])
if len(nums) == 2:
return str(nums[0]) + "/" + str(nums[1])
result = [str(nums[0]) + "/(" + str(nums[1])]
for i in xrange(2, len(nums)):
result += "/" + str(nums[i])
result += ")"
return "".join(result)
460
remove-all-adjacent-duplicates-in-string-ii.py
# Given a string s, a k duplicate removal consists of choosing k adjacent and
# equal letters from s and removing them causing the left and the right side of
# the deleted substring to concatenate together.
#
# We repeatedly make k duplicate removals on s until we no longer can.
#
# Return the final string after all such duplicate removals have been made.
#
# It is guaranteed that the answer is unique.
#
#
# Example 1:
#
# Input: s = "abcd", k = 2
# Output: "abcd"
# Explanation: There's nothing to delete.
#
# Example 2:
#
# Input: s = "deeedbbcccbdaa", k = 3
# Output: "aa"
# Explanation:
# First delete "eee" and "ccc", get "ddbbbdaa"
# Then delete "bbb", get "dddaa"
# Finally delete "ddd", get "aa"
#
# Example 3:
#
# Input: s = "pbbcggttciiippooaais", k = 2
# Output: "ps"
#
#
#
# Constraints:
#
#
# 1 <= s.length <= 10^5
# 2 <= k <= 10^4
# s only contains lower case English letters.# Time: O(n)
# Space: O(n)
class Solution(object):
def removeDuplicates(self, s, k):
"""
:type s: str
:type k: int
:rtype: str
"""
stk = [['^', 0]]
for c in s:
if stk[-1][0] == c:
stk[-1][1] += 1
if stk[-1][1] == k:
stk.pop()
else:
stk.append([c, 1])
return "".join(c*k for c, k in stk)
461
clone-graph.py
# Given a reference of a node in a connected undirected graph.
#
# Return a deep copy (clone) of the graph.
#
# Each node in the graph contains a val (int) and a list (List[Node]) of its
# neighbors.
#
# class Node {
# public int val;
# public List<Node> neighbors;
# }
#
#
#
#
# Test case format:
#
# For simplicity sake, each node's value is the same as the node's index
# (1-indexed). For example, the first node with val = 1, the second node with val
# = 2, and so on. The graph is represented in the test case using an adjacency
# list.
#
# Adjacency list is a collection of unordered lists used to represent a finite
# graph. Each list describes the set of neighbors of a node in the graph.
#
# The given node will always be the first node with val = 1. You must return the
# copy of the given node as a reference to the cloned graph.
#
#
# Example 1:
#
# Input: adjList = [[2,4],[1,3],[2,4],[1,3]]
# Output: [[2,4],[1,3],[2,4],[1,3]]
# Explanation: There are 4 nodes in the graph.
# 1st node (val = 1)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
# 2nd node (val = 2)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
# 3rd node (val = 3)'s neighbors are 2nd node (val = 2) and 4th node (val = 4).
# 4th node (val = 4)'s neighbors are 1st node (val = 1) and 3rd node (val = 3).
#
#
# Example 2:
#
# Input: adjList = [[]]
# Output: [[]]
# Explanation: Note that the input contains one empty list. The graph consists
# of only one node with val = 1 and it does not have any neighbors.
#
#
# Example 3:
#
# Input: adjList = []
# Output: []
# Explanation: This an empty graph, it does not have any nodes.
#
#
# Example 4:
#
# Input: adjList = [[2],[1]]
462
# Output: [[2],[1]]
#
#
#
# Constraints:
#
#
# 1 <= Node.val <= 100
# Node.val is unique for each node.
# Number of Nodes will not exceed 100.
# There is no repeated edges and no self-loops in the graph.
# The Graph is connected and all nodes can be visited starting from the
# given node.# Time: O(n)
# Space: O(n)
class UndirectedGraphNode(object):
def __init__(self, x):
self.label = x
self.neighbors = []
class Solution(object):
# @param node, a undirected graph node
# @return a undirected graph node
def cloneGraph(self, node):
if node is None:
return None
cloned_node = UndirectedGraphNode(node.label)
cloned, queue = {node:cloned_node}, [node]
while queue:
current = queue.pop()
for neighbor in current.neighbors:
if neighbor not in cloned:
queue.append(neighbor)
cloned_neighbor = UndirectedGraphNode(neighbor.label)
cloned[neighbor] = cloned_neighbor
cloned[current].neighbors.append(cloned[neighbor])
return cloned[node]
463
wiggle-sort-ii.py
# Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2]
# < nums[3]....
#
# Example 1:
#
# Input: nums = [1, 5, 1, 1, 6, 4]
# Output: One possible answer is [1, 4, 1, 5, 1, 6].
#
# Example 2:
#
# Input: nums = [1, 3, 2, 2, 3, 1]
# Output: One possible answer is [2, 3, 1, 3, 1, 2].
#
# Note:
#
# You may assume all input has valid answer.
#
# Follow Up:
#
# Can you do it in O(n) time and/or in-place with O(1) extra space?# Time: O(nlogn)
# Space: O(n)
class Solution(object):
def wiggleSort(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
nums.sort()
med = (len(nums) - 1) / 2
nums[::2], nums[1::2] = nums[med::-1], nums[:med:-1]
464
for i in xrange(left, right):
if nums[i] > pivot_value:
nums[i], nums[new_pivot_idx] = nums[new_pivot_idx], nums[i]
new_pivot_idx += 1
nums[right], nums[new_pivot_idx] = nums[new_pivot_idx], nums[right]
return new_pivot_idx
N = len(nums) / 2 * 2 + 1
i, j, n = 0, 0, len(nums) - 1
while j <= n:
if nums[idx(j, N)] > val:
nums[idx(i, N)], nums[idx(j, N)] = nums[idx(j, N)], nums[idx(i, N)]
i += 1
j += 1
elif nums[idx(j, N)] < val:
nums[idx(j, N)], nums[idx(n, N)] = nums[idx(n, N)], nums[idx(j, N)]
n -= 1
else:
j += 1
mid = (len(nums) - 1) / 2
findKthLargest(nums, mid + 1)
reversedTriPartitionWithVI(nums, nums[mid])
465
unique-binary-search-trees-ii.py
# Given an integer n, generate all structurally unique BST's (binary search
# trees) that store values 1 ... n.
#
# Example:
#
# Input: 3
# Output:
# [
# [1,null,3,2],
# [3,2,null,1],
# [3,1,null,null,2],
# [2,1,3],
# [1,null,2,null,3]
# ]
# Explanation:
# The above output corresponds to the 5 unique BST's shown below:
#
# 1 3 3 2 1
# \ / / / \ \
# 3 2 1 1 3 2
# / / \ \
# 2 1 2 3
#
#
#
# Constraints:
#
#
# 0 <= n <= 8# Time: O(4^n / n^(3/2)) ~= Catalan numbers
# Space: O(4^n / n^(3/2)) ~= Catalan numbers
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def __repr__(self):
if self:
serial = []
queue = [self]
while queue:
cur = queue[0]
if cur:
serial.append(cur.val)
queue.append(cur.left)
queue.append(cur.right)
else:
serial.append("#")
queue = queue[1:]
return repr(serial)
466
else:
return None
class Solution(object):
# @return a list of tree node
def generateTrees(self, n):
return self.generateTreesRecu(1, n)
467
remove-nth-node-from-end-of-list.py
# Given a linked list, remove the n-th node from the end of list and return its
# head.
#
# Example:
#
# Given linked list: 1->2->3->4->5, and n = 2.
#
# After removing the second node from the end, the linked list becomes
# 1->2->3->5.
#
#
# Note:
#
# Given n will always be valid.
#
# Follow up:
#
# Could you do this in one pass?# Time: O(n)
# Space: O(1)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self is None:
return "Nil"
else:
return "{} -> {}".format(self.val, repr(self.next))
class Solution(object):
# @return a ListNode
def removeNthFromEnd(self, head, n):
dummy = ListNode(-1)
dummy.next = head
slow, fast = dummy, dummy
for i in xrange(n):
fast = fast.next
while fast.next:
slow, fast = slow.next, fast.next
slow.next = slow.next.next
return dummy.next
468
valid-square.py
# Given the coordinates of four points in 2D space, return whether the four
# points could construct a square.
#
# The coordinate (x,y) of a point is represented by an integer array with two
# integers.
#
# Example:
#
# Input: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1]
# Output: True
#
#
#
#
# Note:
#
#
# All the input integers are in the range [-10000, 10000].
# A valid square has four equal sides with positive length and four equal
# angles (90-degree angles).
# Input points have no order.# Time: O(1)
# Space: O(1)
class Solution(object):
def validSquare(self, p1, p2, p3, p4):
"""
:type p1: List[int]
:type p2: List[int]
:type p3: List[int]
:type p4: List[int]
:rtype: bool
"""
def dist(p1, p2):
return (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2
469
water-and-jug-problem.py
# You are given two jugs with capacities x and y litres. There is an infinite
# amount of water supply available. You need to determine whether it is possible
# to measure exactly z litres using these two jugs.
#
# If z liters of water is measurable, you must have z liters of water contained
# within one or both buckets by the end.
#
# Operations allowed:
#
#
# Fill any of the jugs completely with water.
# Empty any of the jugs.
# Pour water from one jug into another till the other jug is completely
# full or the first jug itself is empty.
#
#
# Example 1: (From the famous "Die Hard" example)
#
# Input: x = 3, y = 5, z = 4
# Output: True
#
#
# Example 2:
#
# Input: x = 2, y = 6, z = 5
# Output: False
#
#
# Constraints:
#
#
# 0 <= x <= 10^6
# 0 <= y <= 10^6
# 0 <= z <= 10^6# Time: O(logn), n is the max of (x, y)
# Space: O(1)
class Solution(object):
def canMeasureWater(self, x, y, z):
"""
:type x: int
:type y: int
:type z: int
:rtype: bool
"""
def gcd(a, b):
while b:
a, b = b, a%b
return a
470
delete-columns-to-make-sorted-ii.py
# Example 3:
#
# Input: ["zyx","wvu","tsr"]
# Output: 3
# Explanation:
# We have to delete every column.
#
#
#
#
#
#
# Note:
#
#
# 1 <= A.length <= 100
# 1 <= A[i].length <= 100# Time: O(n * l)
# Space: O(n)
class Solution(object):
def minDeletionSize(self, A):
"""
:type A: List[str]
:rtype: int
"""
result = 0
unsorted = set(range(len(A)-1))
for j in xrange(len(A[0])):
if any(A[i][j] > A[i+1][j] for i in unsorted):
result += 1
else:
unsorted -= set(i for i in unsorted if A[i][j] < A[i+1][j])
return result
# Time: O(n * m)
# Space: O(n)
class Solution2(object):
def minDeletionSize(self, A):
"""
:type A: List[str]
:rtype: int
"""
result = 0
is_sorted = [False]*(len(A)-1)
for j in xrange(len(A[0])):
tmp = is_sorted[:]
for i in xrange(len(A)-1):
if A[i][j] > A[i+1][j] and tmp[i] == False:
result += 1
break
if A[i][j] < A[i+1][j]:
tmp[i] = True
else:
is_sorted = tmp
return result
471
evaluate-reverse-polish-notation.py
# Evaluate the value of an arithmetic expression in Reverse Polish Notation.
#
# Valid operators are +, -, *, /. Each operand may be an integer or another
# expression.
#
# Note:
#
#
# Division between two integers should truncate toward zero.
# The given RPN expression is always valid. That means the expression
# would always evaluate to a result and there won't be any divide by zero
# operation.
#
#
# Example 1:
#
# Input: ["2", "1", "+", "3", "*"]
# Output: 9
# Explanation: ((2 + 1) * 3) = 9
#
#
# Example 2:
#
# Input: ["4", "13", "5", "/", "+"]
# Output: 6
# Explanation: (4 + (13 / 5)) = 6
#
#
# Example 3:
#
# Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
# Output: 22
# Explanation:
# ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
# = ((10 * (6 / (12 * -11))) + 17) + 5
# = ((10 * (6 / -132)) + 17) + 5
# = ((10 * 0) + 17) + 5
# = (0 + 17) + 5
# = 17 + 5
# = 22# Time: O(n)
# Space: O(n)
import operator
class Solution(object):
# @param tokens, a list of string
# @return an integer
def evalRPN(self, tokens):
numerals, operators = [], {"+": operator.add, "-": operator.sub, "*": operator.mul, "/": operator.div}
for token in tokens:
if token not in operators:
numerals.append(int(token))
else:
y, x = numerals.pop(), numerals.pop()
numerals.append(int(operators[token](x * 1.0, y)))
return numerals.pop()
472
validate-ip-address.py
# Given a string IP. We need to check If IP is a valid IPv4 address, valid IPv6
# address or not a valid IP address.
#
# Return "IPv4" if IP is a valid IPv4 address, "IPv6" if IP is a valid IPv6
# address or "Neither" if IP is not a valid IP of any type.
#
# A valid IPv4 address is an IP in the form "x1.x2.x3.x4" where 0 <= xi <= 255
# and xi cannot contain leading zeros. For example, "192.168.1.1"
# and "192.168.1.0" are valid IPv4 addresses but "192.168.01.1",
# "192.168.1.00" and "[email protected]" are invalid IPv4 adresses.
#
# A valid IPv6 address is an IP in the form "x1:x2:x3:x4:x5:x6:x7:x8" where:
#
#
# 1 <= xi.length <= 4
# xi is hexadecimal string whcih may contain digits, lower-case English
# letter ('a' to 'f') and/or upper-case English letters ('A' to 'F').
# Leading zeros are allowed in xi.
#
#
# For example, "2001:0db8:85a3:0000:0000:8a2e:0370:7334" and
# "2001:db8:85a3:0:0:8A2E:0370:7334" are valid IPv6 addresses but
# "2001:0db8:85a3::8A2E:037j:7334" and "02001:0db8:85a3:0000:0000:8a2e:0370:7334"
# are invalid IPv6 addresses.
#
#
# Example 1:
#
# Input: IP = "172.16.254.1"
# Output: "IPv4"
# Explanation: This is a valid IPv4 address, return "IPv4".
#
#
# Example 2:
#
# Input: IP = "2001:0db8:85a3:0:0:8A2E:0370:7334"
# Output: "IPv6"
# Explanation: This is a valid IPv6 address, return "IPv6".
#
#
# Example 3:
#
# Input: IP = "256.256.256.256"
# Output: "Neither"
# Explanation: This is neither a IPv4 address nor a IPv6 address.
#
#
# Example 4:
#
# Input: IP = "2001:0db8:85a3:0:0:8A2E:0370:7334:"
# Output: "Neither"
#
#
# Example 5:
#
# Input: IP = "1e1.4.5.6"
# Output: "Neither"
#
473
#
#
# Constraints:
#
#
# IP consists only of English letters, digits and the characters '.' and
# ':'.# Time: O(1)
# Space: O(1)
import string
class Solution(object):
def validIPAddress(self, IP):
"""
:type IP: str
:rtype: str
"""
blocks = IP.split('.')
if len(blocks) == 4:
for i in xrange(len(blocks)):
if not blocks[i].isdigit() or not 0 <= int(blocks[i]) < 256 or \
(blocks[i][0] == '0' and len(blocks[i]) > 1):
return "Neither"
return "IPv4"
blocks = IP.split(':')
if len(blocks) == 8:
for i in xrange(len(blocks)):
if not (1 <= len(blocks[i]) <= 4) or \
not all(c in string.hexdigits for c in blocks[i]):
return "Neither"
return "IPv6"
return "Neither"
474
single-number-iii.py
# Given an integer array nums, in which exactly two elements appear only once
# and all the other elements appear exactly twice. Find the two elements that
# appear only once. You can return the answer in any order.
#
# Follow up: Your algorithm should run in linear runtime complexity. Could you
# implement it using only constant space complexity?
#
#
# Example 1:
#
# Input: nums = [1,2,1,3,2,5]
# Output: [3,5]
# Explanation: [5, 3] is also a valid answer.
#
#
# Example 2:
#
# Input: nums = [-1,0]
# Output: [-1,0]
#
#
# Example 3:
#
# Input: nums = [0,1]
# Output: [1,0]
#
#
#
# Constraints:
#
#
# 1 <= nums.length <= 30000
# Each integer in nums will appear twice, only two integers will appear
# once.# Time: O(n)
# Space: O(1)
import operator
import collections
class Solution(object):
# @param {integer[]} nums
# @return {integer[]}
def singleNumber(self, nums):
x_xor_y = reduce(operator.xor, nums)
bit = x_xor_y & -x_xor_y
result = [0, 0]
for i in nums:
result[bool(i & bit)] ^= i
return result
class Solution2(object):
# @param {integer[]} nums
# @return {integer[]}
def singleNumber(self, nums):
x_xor_y = 0
for i in nums:
475
x_xor_y ^= i
x = 0
for i in nums:
if i & bit:
x ^= i
class Solution3(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
return [x[0] for x in sorted(collections.Counter(nums).items(), key=lambda i: i[1], reverse=False)[:2]]
476
four-divisors.py
# Given an integer array nums, return the sum of divisors of the integers in
# that array that have exactly four divisors.
#
# If there is no such integer in the array, return 0.
#
#
# Example 1:
#
# Input: nums = [21,4,7]
# Output: 32
# Explanation:
# 21 has 4 divisors: 1, 3, 7, 21
# 4 has 3 divisors: 1, 2, 4
# 7 has 2 divisors: 1, 7
# The answer is the sum of divisors of 21 only.
#
#
#
# Constraints:
#
#
# 1 <= nums.length <= 10^4
# 1 <= nums[i] <= 10^5# Time: O(n * sqrt(n))
# Space: O(1)
class Solution(object):
def sumFourDivisors(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
result = 0
for num in nums:
facs, i = [], 1
while i*i <= num:
if num % i:
i+= 1
continue
facs.append(i)
if i != num//i:
facs.append(num//i)
if len(facs) > 4:
break
i += 1
if len(facs) == 4:
result += sum(facs)
return result
class Solution2(object):
def sumFourDivisors(self, nums):
"""
:type nums: List[int]
477
:rtype: int
"""
def factorize(x):
result = []
d = 2
while d*d <= x:
e = 0
while x%d == 0:
x //= d
e += 1
if e:
result.append([d, e])
d += 1 if d == 2 else 2
if x > 1:
result.append([x, 1])
return result
result = 0
for facs in itertools.imap(factorize, nums):
if len(facs) == 1 and facs[0][1] == 3:
p = facs[0][0]
result += (p**4-1)//(p-1) # p^0 + p^1 +p^2 +p^3
elif len(facs) == 2 and facs[0][1] == facs[1][1] == 1:
p, q = facs[0][0], facs[1][0]
result += (1 + p) * (1 + q)
return result
478
next-permutation.py
# Implement next permutation, which rearranges numbers into the
# lexicographically next greater permutation of numbers.
#
# If such arrangement is not possible, it must rearrange it as the lowest
# possible order (ie, sorted in ascending order).
#
# The replacement must be in-place and use only constant extra memory.
#
# Here are some examples. Inputs are in the left-hand column and its
# corresponding outputs are in the right-hand column.
#
# 1,2,3 → 1,3,2
#
# 3,2,1 → 1,2,3
#
# 1,1,5 → 1,5,1# Time: O(n)
# Space: O(1)
class Solution(object):
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
k, l = -1, 0
for i in reversed(xrange(len(nums)-1)):
if nums[i] < nums[i+1]:
k = i
break
else:
nums.reverse()
return
# Time: O(n)
# Space: O(1)
class Solution2(object):
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
k, l = -1, 0
for i in xrange(len(nums)-1):
if nums[i] < nums[i+1]:
k = i
if k == -1:
nums.reverse()
return
479
for i in xrange(k+1, len(nums)):
if nums[i] > nums[k]:
l = i
nums[k], nums[l] = nums[l], nums[k]
nums[k+1:] = nums[:k:-1]
480
longest-string-chain.py
# Given a list of words, each word consists of English lowercase letters.
#
# Let's say word1 is a predecessor of word2 if and only if we can add exactly
# one letter anywhere in word1 to make it equal to word2. For example, "abc" is a
# predecessor of "abac".
#
# A word chain is a sequence of words [word_1, word_2, ..., word_k] with k >=
# 1, where word_1 is a predecessor of word_2, word_2 is a predecessor of word_3,
# and so on.
#
# Return the longest possible length of a word chain with words chosen from the
# given list of words.
#
#
#
# Example 1:
#
# Input: ["a","b","ba","bca","bda","bdca"]
# Output: 4
# Explanation: one of the longest word chain is "a","ba","bda","bdca".
#
#
#
#
# Note:
#
#
# 1 <= words.length <= 1000
# 1 <= words[i].length <= 16
# words[i] only consists of English lowercase letters.# Time: O(n * l^2)
# Space: O(n * l)
import collections
class Solution(object):
def longestStrChain(self, words):
"""
:type words: List[str]
:rtype: int
"""
words.sort(key=len)
dp = collections.defaultdict(int)
for w in words:
for i in xrange(len(w)):
dp[w] = max(dp[w], dp[w[:i]+w[i+1:]]+1)
return max(dp.itervalues())
481
reduce-array-size-to-the-half.py
# Given an array arr. You can choose a set of integers and remove all the
# occurrences of these integers in the array.
#
# Return the minimum size of the set so that at least half of the integers of
# the array are removed.
#
#
# Example 1:
#
# Input: arr = [3,3,3,3,5,5,5,2,2,7]
# Output: 2
# Explanation: Choosing {3,7} will make the new array [5,5,5,2,2] which has size
# 5 (i.e equal to half of the size of the old array).
# Possible sets of size 2 are {3,5},{3,2},{5,2}.
# Choosing set {2,7} is not possible as it will make the new array
# [3,3,3,3,5,5,5] which has size greater than half of the size of the old array.
#
#
# Example 2:
#
# Input: arr = [7,7,7,7,7,7]
# Output: 1
# Explanation: The only possible set you can choose is {7}. This will make the
# new array empty.
#
#
# Example 3:
#
# Input: arr = [1,9]
# Output: 1
#
#
# Example 4:
#
# Input: arr = [1000,1000,3,7]
# Output: 1
#
#
# Example 5:
#
# Input: arr = [1,2,3,4,5,6,7,8,9,10]
# Output: 5
#
#
#
# Constraints:
#
#
# 1 <= arr.length <= 10^5
# arr.length is even.
# 1 <= arr[i] <= 10^5# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def minSetSize(self, arr):
482
"""
:type arr: List[int]
:rtype: int
"""
counting_sort = [0]*len(arr)
count = collections.Counter(arr)
for c in count.itervalues():
counting_sort[c-1] += 1
result, total = 0, 0
for c in reversed(xrange(len(arr))):
if not counting_sort[c]:
continue
count = min(counting_sort[c],
((len(arr)+1)//2 - total - 1)//(c+1) + 1)
result += count
total += count*(c+1)
if total >= (len(arr)+1)//2:
break
return result
483
ugly-number-ii.py
# Write a program to find the n-th ugly number.
#
# Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.
#
# Example:
#
# Input: n = 10
# Output: 12
# Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10
# ugly numbers.
#
# Note:
#
#
# 1 is typically treated as an ugly number.
# n does not exceed 1690.# Time: O(n)
# Space: O(1)
import heapq
class Solution(object):
# @param {integer} n
# @return {integer}
def nthUglyNumber(self, n):
ugly_number = 0
heap = []
heapq.heappush(heap, 1)
for _ in xrange(n):
ugly_number = heapq.heappop(heap)
if ugly_number % 2 == 0:
heapq.heappush(heap, ugly_number * 2)
elif ugly_number % 3 == 0:
heapq.heappush(heap, ugly_number * 2)
heapq.heappush(heap, ugly_number * 3)
else:
heapq.heappush(heap, ugly_number * 2)
heapq.heappush(heap, ugly_number * 3)
heapq.heappush(heap, ugly_number * 5)
return ugly_number
484
if u > ugly:
ugly = u
n -= 1
q2 += 2 * u,
q3 += 3 * u,
q5 += 5 * u,
class Solution2(object):
ugly = sorted(2**a * 3**b * 5**c
for a in range(32) for b in range(20) for c in range(14))
485
design-circular-deque.py
# Design your implementation of the circular double-ended queue (deque).
#
# Your implementation should support following operations:
#
#
# MyCircularDeque(k): Constructor, set the size of the deque to be k.
# insertFront(): Adds an item at the front of Deque. Return true if the
# operation is successful.
# insertLast(): Adds an item at the rear of Deque. Return true if the
# operation is successful.
# deleteFront(): Deletes an item from the front of Deque. Return true if
# the operation is successful.
# deleteLast(): Deletes an item from the rear of Deque. Return true if the
# operation is successful.
# getFront(): Gets the front item from the Deque. If the deque is empty,
# return -1.
# getRear(): Gets the last item from Deque. If the deque is empty, return
# -1.
# isEmpty(): Checks whether Deque is empty or not.
# isFull(): Checks whether Deque is full or not.
#
#
#
#
# Example:
#
# MyCircularDeque circularDeque = new MycircularDeque(3); // set the size to be
# 3
# circularDeque.insertLast(1); // return true
# circularDeque.insertLast(2); // return true
# circularDeque.insertFront(3); // return true
# circularDeque.insertFront(4); // return false, the queue is
# full
# circularDeque.getRear(); // return 2
# circularDeque.isFull(); // return true
# circularDeque.deleteLast(); // return true
# circularDeque.insertFront(4); // return true
# circularDeque.getFront(); // return 4
#
#
#
#
# Note:
#
#
# All values will be in the range of [0, 1000].
# The number of operations will be in the range of [1, 1000].
# Please do not use the built-in Deque library.# Time: O(1)
# Space: O(k)
class MyCircularDeque(object):
486
self.__size = 0
self.__buffer = [0] * k
def deleteFront(self):
"""
Deletes an item from the front of Deque. Return true if the operation is successful.
:rtype: bool
"""
if self.isEmpty():
return False
self.__start = (self.__start+1) % len(self.__buffer)
self.__size -= 1
return True
def deleteLast(self):
"""
Deletes an item from the rear of Deque. Return true if the operation is successful.
:rtype: bool
"""
if self.isEmpty():
return False
self.__size -= 1
return True
def getFront(self):
"""
Get the front item from the deque.
:rtype: int
"""
return -1 if self.isEmpty() else self.__buffer[self.__start]
def getRear(self):
"""
Get the last item from the deque.
:rtype: int
487
"""
return -1 if self.isEmpty() else self.__buffer[(self.__start+self.__size-1) % len(self.__buffer)]
def isEmpty(self):
"""
Checks whether the circular deque is empty or not.
:rtype: bool
"""
return self.__size == 0
def isFull(self):
"""
Checks whether the circular deque is full or not.
:rtype: bool
"""
return self.__size == len(self.__buffer)
488
smallest-integer-divisible-by-k.py
# Given a positive integer K, you need find the smallest positive integer N such
# that N is divisible by K, and N only contains the digit 1.
#
# Return the length of N. If there is no such N, return -1.
#
#
#
# Example 1:
#
# Input: 1
# Output: 1
# Explanation: The smallest answer is N = 1, which has length 1.
#
# Example 2:
#
# Input: 2
# Output: -1
# Explanation: There is no such positive integer N divisible by 2.
#
# Example 3:
#
# Input: 3
# Output: 3
# Explanation: The smallest answer is N = 111, which has length 3.
#
#
#
# Note:
#
#
# 1 <= K <= 10^5# Time: O(k)
# Space: O(1)
class Solution(object):
def smallestRepunitDivByK(self, K):
"""
:type K: int
:rtype: int
"""
# by observation, K % 2 = 0 or K % 5 = 0, it is impossible
if K % 2 == 0 or K % 5 == 0:
return -1
489
result = (result*10+1) % K
if not result:
return N
assert(False)
return -1 # never reach
490
dota2-senate.py
# In the world of Dota2, there are two parties: the Radiant and the Dire.
#
# The Dota2 senate consists of senators coming from two parties. Now the senate
# wants to make a decision about a change in the Dota2 game. The voting for this
# change is a round-based procedure. In each round, each senator can exercise one
# of the two rights:
#
#
# Ban one senator's right:
#
# A senator can make another senator lose all his rights in this and all
# the following rounds.
# Announce the victory:
#
# If this senator found the senators who still have rights to vote are all
# from the same party, he can announce the victory and make the decision about the
# change in the game.
#
#
#
#
# Given a string representing each senator's party belonging. The character 'R'
# and 'D' represent the Radiant party and the Dire party respectively. Then if
# there are n senators, the size of the given string will be n.
#
# The round-based procedure starts from the first senator to the last senator in
# the given order. This procedure will last until the end of voting. All the
# senators who have lost their rights will be skipped during the procedure.
#
# Suppose every senator is smart enough and will play the best strategy for his
# own party, you need to predict which party will finally announce the victory and
# make the change in the Dota2 game. The output should be Radiant or Dire.
#
# Example 1:
#
# Input: "RD"
# Output: "Radiant"
# Explanation: The first senator comes from Radiant and he can just ban the next
# senator's right in the round 1.
# And the second senator can't exercise any rights any more since his right has
# been banned.
# And in the round 2, the first senator can just announce the victory since he
# is the only guy in the senate who can vote.
#
#
#
#
# Example 2:
#
# Input: "RDD"
# Output: "Dire"
# Explanation:
# The first senator comes from Radiant and he can just ban the next senator's
# right in the round 1.
# And the second senator can't exercise any rights anymore since his right has
# been banned.
# And the third senator comes from Dire and he can ban the first senator's right
# in the round 1.
491
# And in the round 2, the third senator can just announce the victory since he
# is the only guy in the senate who can vote.
#
#
#
#
# Note:
#
#
# The length of the given string will in the range [1, 10,000].# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def predictPartyVictory(self, senate):
"""
:type senate: str
:rtype: str
"""
n = len(senate)
radiant, dire = collections.deque(), collections.deque()
for i, c in enumerate(senate):
if c == 'R':
radiant.append(i)
else:
dire.append(i)
while radiant and dire:
r_idx, d_idx = radiant.popleft(), dire.popleft()
if r_idx < d_idx:
radiant.append(r_idx+n)
else:
dire.append(d_idx+n)
return "Radiant" if len(radiant) > len(dire) else "Dire"
492
wiggle-subsequence.py
# A sequence of numbers is called a wiggle sequence if the differences between
# successive numbers strictly alternate between positive and negative. The first
# difference (if one exists) may be either positive or negative. A sequence with
# fewer than two elements is trivially a wiggle sequence.
#
# For example, [1,7,4,9,2,5] is a wiggle sequence because the differences
# (6,-3,5,-7,3) are alternately positive and negative. In contrast, [1,4,7,2,5]
# and [1,7,4,5,5] are not wiggle sequences, the first because its first two
# differences are positive and the second because its last difference is zero.
#
# Given a sequence of integers, return the length of the longest subsequence
# that is a wiggle sequence. A subsequence is obtained by deleting some number of
# elements (eventually, also zero) from the original sequence, leaving the
# remaining elements in their original order.
#
# Example 1:
#
# Input: [1,7,4,9,2,5]
# Output: 6
# Explanation: The entire sequence is a wiggle sequence.
#
#
# Example 2:
#
# Input: [1,17,5,10,13,15,10,5,16,8]
# Output: 7
# Explanation: There are several subsequences that achieve this length. One is
# [1,17,10,13,10,16,8].
#
#
# Example 3:
#
# Input: [1,2,3,4,5,6,7,8,9]
# Output: 2
#
# Follow up:
#
# Can you do it in O(n) time?# Time: O(n)
# Space: O(1)
class Solution(object):
def wiggleMaxLength(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) < 2:
return len(nums)
length, up = 1, None
493
return length
494
gas-station.py
# There are N gas stations along a circular route, where the amount of gas at
# station i is gas[i].
#
# You have a car with an unlimited gas tank and it costs cost[i] of gas to
# travel from station i to its next station (i+1). You begin the journey with an
# empty tank at one of the gas stations.
#
# Return the starting gas station's index if you can travel around the circuit
# once in the clockwise direction, otherwise return -1.
#
# Note:
#
#
# If there exists a solution, it is guaranteed to be unique.
# Both input arrays are non-empty and have the same length.
# Each element in the input arrays is a non-negative integer.
#
#
# Example 1:
#
# Input:
# gas = [1,2,3,4,5]
# cost = [3,4,5,1,2]
#
# Output: 3
#
# Explanation:
# Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4
# = 4
# Travel to station 4. Your tank = 4 - 1 + 5 = 8
# Travel to station 0. Your tank = 8 - 2 + 1 = 7
# Travel to station 1. Your tank = 7 - 3 + 2 = 6
# Travel to station 2. Your tank = 6 - 4 + 3 = 5
# Travel to station 3. The cost is 5. Your gas is just enough to travel back to
# station 3.
# Therefore, return 3 as the starting index.
#
#
# Example 2:
#
# Input:
# gas = [2,3,4]
# cost = [3,4,3]
#
# Output: -1
#
# Explanation:
# You can't start at station 0 or 1, as there is not enough gas to travel to the
# next station.
# Let's start at station 2 and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
# Travel to station 0. Your tank = 4 - 3 + 2 = 3
# Travel to station 1. Your tank = 3 - 3 + 3 = 3
# You cannot travel back to station 2, as it requires 4 unit of gas but you only
# have 3.
# Therefore, you can't travel around the circuit once no matter where you start.# Time: O(n)
# Space: O(1)
class Solution(object):
495
# @param gas, a list of integers
# @param cost, a list of integers
# @return an integer
def canCompleteCircuit(self, gas, cost):
start, total_sum, current_sum = 0, 0, 0
for i in xrange(len(gas)):
diff = gas[i] - cost[i]
current_sum += diff
total_sum += diff
if current_sum < 0:
start = i + 1
current_sum = 0
if total_sum >= 0:
return start
return -1
496
deepest-leaves-sum.py
# Given a binary tree, return the sum of values of its deepest leaves.
#
# Example 1:
#
#
#
# Input: root = [1,2,3,4,5,null,6,7,null,null,null,null,8]
# Output: 15
#
#
#
# Constraints:
#
#
# The number of nodes in the tree is between 1 and 10^4.
# The value of nodes is between 1 and 100.# Time: O(n)
# Space: O(w)
class Solution(object):
def deepestLeavesSum(self, root):
"""
:type root: TreeNode
:rtype: int
"""
curr = [root]
while curr:
prev, curr = curr, [child for p in curr for child in [p.left, p.right] if child]
return sum(node.val for node in prev)
497
check-if-word-is-valid-after-substitutions.py
# We can say that a string is valid if it follows one of the three following
# cases:
#
#
# An empty string "" is valid.
# The string "abc" is also valid.
# Any string in the form "a" + str + "bc", "ab" + str + "c", str + "abc"
# or "abc" + str where str is a valid string is also considered a valid string.
#
#
# For example, "", "abc", "aabcbc", "abcabc" and "abcabcababcc" are all valid
# strings, while "abccba", "ab", "cababc" and "bac" are not valid strings.
#
# Given a string s, return true if it is a valid string, otherwise, return
# false.
#
#
# Example 1:
#
# Input: s = "aabcbc"
# Output: true
# Explanation:
# We start with the valid string "abc".
# Then we can insert another "abc" between "a" and "bc", resulting in "a" +
# "abc" + "bc" which is "aabcbc".
#
#
# Example 2:
#
# Input: s = "abcabcababcc"
# Output: true
# Explanation:
# "abcabcabc" is valid after consecutive insertings of "abc".
# Then we can insert "abc" before the last letter, resulting in "abcabcab" +
# "abc" + "c" which is "abcabcababcc".
#
#
# Example 3:
#
# Input: s = "abccba"
# Output: false
#
#
# Example 4:
#
# Input: s = "cababc"
# Output: false
#
#
#
# Constraints:
#
#
# 1 <= s.length <= 2 * 104
# s[i] is 'a', 'b', or 'c'# Time: O(n)
# Space: O(n)
class Solution(object):
498
def isValid(self, S):
"""
:type S: str
:rtype: bool
"""
stack = []
for i in S:
if i == 'c':
if stack[-2:] == ['a', 'b']:
stack.pop()
stack.pop()
else:
return False
else:
stack.append(i)
return not stack
499
subsets-ii.py
# Given a collection of integers that might contain duplicates, nums, return all
# possible subsets (the power set).
#
# Note: The solution set must not contain duplicate subsets.
#
# Example:
#
# Input: [1,2,2]
# Output:
# [
# [2],
# [1],
# [1,2,2],
# [2,2],
# [1,2],
# []
# ]# Time: O(n * 2^n)
# Space: O(1)
class Solution(object):
def subsetsWithDup(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
result = [[]]
previous_size = 0
for i in xrange(len(nums)):
size = len(result)
for j in xrange(size):
# Only union non-duplicate element or new union set.
if i == 0 or nums[i] != nums[i - 1] or j >= previous_size:
result.append(list(result[j]))
result[-1].append(nums[i])
previous_size = size
return result
500
i += 1
return result
501
insufficient-nodes-in-root-to-leaf-paths.py
# Example 2:
#
#
# Input: root = [5,4,8,11,null,17,4,7,1,null,null,5,3], limit = 22
#
# Output: [5,4,8,11,null,17,4,7,null,null,null,5]
#
#
#
# Example 3:
#
#
# Input: root = [1,2,-3,-5,null,4,null], limit = -1
#
# Output: [1,null,-3,4]# Time: O(n)
# Space: O(h)
class Solution(object):
def sufficientSubset(self, root, limit):
"""
:type root: TreeNode
:type limit: int
:rtype: TreeNode
"""
if not root:
return None
if not root.left and not root.right:
return None if root.val < limit else root
root.left = self.sufficientSubset(root.left, limit-root.val)
root.right = self.sufficientSubset(root.right, limit-root.val)
if not root.left and not root.right:
return None
return root
502
maximum-binary-tree-ii.py
# We are given the root node of a maximum tree: a tree where every node has a
# value greater than any other value in its subtree.
#
# Just as in the previous problem, the given tree was constructed from an
# list A (root = Construct(A)) recursively with the following Construct(A)
# routine:
#
#
# If A is empty, return null.
# Otherwise, let A[i] be the largest element of A. Create a root node
# with value A[i].
# The left child of root will be Construct([A[0], A[1], ..., A[i-1]])
# The right child of root will be Construct([A[i+1], A[i+2], ...,
# A[A.length - 1]])
# Return root.
#
#
# Note that we were not given A directly, only a root node root = Construct(A).
#
# Suppose B is a copy of A with the value val appended to it. It is guaranteed
# that B has unique values.
#
# Return Construct(B).
#
#
# Example 1:
#
#
#
# Input: root = [4,1,3,null,null,2], val = 5
# Output: [5,4,null,1,3,null,null,2]
# Explanation: A = [1,4,2,3], B = [1,4,2,3,5]
#
#
# Example 2:
#
#
#
# Input: root = [5,2,4,null,1], val = 3
# Output: [5,2,4,null,1,null,3]
# Explanation: A = [2,1,5,4], B = [2,1,5,4,3]
#
#
# Example 3:
#
#
#
# Input: root = [5,2,3,null,1], val = 4
# Output: [5,2,4,null,1,3]
# Explanation: A = [2,1,5,3], B = [2,1,5,3,4]
#
#
#
# Constraints:
#
#
# 1 <= B.length <= 100# Time: O(h)
# Space: O(1)
503
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def insertIntoMaxTree(self, root, val):
"""
:type root: TreeNode
:type val: int
:rtype: TreeNode
"""
if not root:
return TreeNode(val)
curr = root
while curr.right and curr.right.val > val:
curr = curr.right
node = TreeNode(val)
curr.right, node.left = node, curr.right
return root
504
longest-substring-with-at-least-k-repeating-characters.py
# Find the length of the longest substring T of a given string (consists of
# lowercase letters only) such that every character in T appears no less than k
# times.
#
#
# Example 1:
# Input:
# s = "aaabb", k = 3
#
# Output:
# 3
#
# The longest substring is "aaa", as 'a' is repeated 3 times.
#
#
#
# Example 2:
# Input:
# s = "ababbc", k = 2
#
# Output:
# 5
#
# The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is
# repeated 3 times.# Time: O(26 * n) = O(n)
# Space: O(26) = O(1)
class Solution(object):
def longestSubstring(self, s, k):
"""
:type s: str
:type k: int
:rtype: int
"""
def longestSubstringHelper(s, k, start, end):
count = [0] * 26
for i in xrange(start, end):
count[ord(s[i]) - ord('a')] += 1
max_len = 0
i = start
while i < end:
while i < end and count[ord(s[i]) - ord('a')] < k:
i += 1
j = i
while j < end and count[ord(s[j]) - ord('a')] >= k:
j += 1
505
diagonal-traverse.py
# Given a matrix of M x N elements (M rows, N columns), return all elements of
# the matrix in diagonal order as shown in the below image.
#
#
#
# Example:
#
# Input:
# [
# [ 1, 2, 3 ],
# [ 4, 5, 6 ],
# [ 7, 8, 9 ]
# ]
#
# Output: [1,2,4,7,5,3,6,8,9]
#
# Explanation:
#
#
#
#
#
# Note:
#
# The total number of elements of the given matrix will not exceed 10,000.# Time: O(m * n)
# Space: O(1)
class Solution(object):
def findDiagonalOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
if not matrix or not matrix[0]:
return []
result = []
row, col, d = 0, 0, 0
dirs = [(-1, 1), (1, -1)]
506
d = 1 - d
return result
507
evaluate-division.py
# Equations are given in the format A / B = k, where A and B are variables
# represented as strings, and k is a real number (floating point number). Given
# some queries, return the answers. If the answer does not exist, return -1.0.
#
# Example:
#
# Given a / b = 2.0, b / c = 3.0.
#
# queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? .
#
# return [6.0, 0.5, -1.0, 1.0, -1.0 ].
#
# The input is: vector<pair<string, string>> equations, vector<double>& values,
# vector<pair<string, string>> queries , where equations.size() == values.size(),
# and the values are positive. This represents the equations. Return
# vector<double>.
#
# According to the example above:
#
# equations = [ ["a", "b"], ["b", "c"] ],
# values = [2.0, 3.0],
# queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ].
#
#
#
# The input is always valid. You may assume that evaluating the queries will
# result in no division by zero and there is no contradiction.# Time: O(e + q * |V|!), |V| is the number of va
# Space: O(e)
import collections
class Solution(object):
def calcEquation(self, equations, values, query):
"""
:type equations: List[List[str]]
:type values: List[float]
:type query: List[List[str]]
:rtype: List[float]
"""
def check(up, down, lookup, visited):
if up in lookup and down in lookup[up]:
return (True, lookup[up][down])
for k, v in lookup[up].iteritems():
if k not in visited:
visited.add(k)
tmp = check(k, down, lookup, visited)
if tmp[0]:
return (True, v * tmp[1])
return (False, 0)
lookup = collections.defaultdict(dict)
for i, e in enumerate(equations):
lookup[e[0]][e[1]] = values[i]
if values[i]:
lookup[e[1]][e[0]] = 1.0 / values[i]
result = []
508
for q in query:
visited = set()
tmp = check(q[0], q[1], lookup, visited)
result.append(tmp[1] if tmp[0] else -1)
return result
509
minimum-time-difference.py
# Given a list of 24-hour clock time points in "Hour:Minutes" format, find the
# minimum minutes difference between any two time points in the list.
#
# Example 1:
#
# Input: ["23:59","00:00"]
# Output: 1
#
#
#
# Note:
#
#
# The number of time points in the given list is at least 2 and won't exceed
# 20000.
# The input time is legal and ranges from 00:00 to 23:59.# Time: O(nlogn)
# Space: O(n)
class Solution(object):
def findMinDifference(self, timePoints):
"""
:type timePoints: List[str]
:rtype: int
"""
minutes = map(lambda x: int(x[:2]) * 60 + int(x[3:]), timePoints)
minutes.sort()
return min((y - x) % (24 * 60) \
for x, y in zip(minutes, minutes[1:] + minutes[:1]))
510
binary-tree-zigzag-level-order-traversal.py
# Given a binary tree, return the zigzag level order traversal of its nodes'
# values. (ie, from left to right, then right to left for the next level and
# alternate between).
#
#
# For example:
#
# Given binary tree [3,9,20,null,null,15,7],
#
# 3
# / \
# 9 20
# / \
# 15 7
#
#
#
# return its zigzag level order traversal as:
#
# [
# [3],
# [20,9],
# [15,7]
# ]# Time: O(n)
# Space: O(n)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
# @param root, a tree node
# @return a list of lists of integers
def zigzagLevelOrder(self, root):
if root is None:
return []
result, current = [], [root]
while current:
next_level, vals = [], []
for node in current:
vals.append(node.val)
if node.left:
next_level.append(node.left)
if node.right:
next_level.append(node.right)
result.append(vals[::-1] if len(result) % 2 else vals)
current = next_level
return result
511
minimum-score-triangulation-of-polygon.py
# Given N, consider a convex N-sided polygon with vertices labelled A[0], A[i],
# ..., A[N-1] in clockwise order.
#
# Suppose you triangulate the polygon into N-2 triangles. For each triangle,
# the value of that triangle is the product of the labels of the vertices, and the
# total score of the triangulation is the sum of these values over all N-2
# triangles in the triangulation.
#
# Return the smallest possible total score that you can achieve with some
# triangulation of the polygon.
#
#
#
#
#
#
#
# Example 1:
#
# Input: [1,2,3]
# Output: 6
# Explanation: The polygon is already triangulated, and the score of the only
# triangle is 6.
#
#
#
# Example 2:
#
#
#
# Input: [3,7,4,5]
# Output: 144
# Explanation: There are two triangulations, with possible scores: 3*7*5 + 4*5*7
# = 245, or 3*4*5 + 3*4*7 = 144. The minimum score is 144.
#
#
#
# Example 3:
#
# Input: [1,3,1,4,1,5]
# Output: 13
# Explanation: The minimum score triangulation has score 1*1*3 + 1*1*4 + 1*1*5 +
# 1*1*1 = 13.
#
#
#
#
# Note:
#
#
# 3 <= A.length <= 50
# 1 <= A[i] <= 100# Time: O(n^3)
# Space: O(n^2)
class Solution(object):
def minScoreTriangulation(self, A):
"""
:type A: List[int]
512
:rtype: int
"""
dp = [[0 for _ in xrange(len(A))] for _ in xrange(len(A))]
for p in xrange(3, len(A)+1):
for i in xrange(len(A)-p+1):
j = i+p-1;
dp[i][j] = float("inf")
for k in xrange(i+1, j):
dp[i][j] = min(dp[i][j], dp[i][k]+dp[k][j] + A[i]*A[j]*A[k])
return dp[0][-1]
513
multiply-strings.py
# Given two non-negative integers num1 and num2 represented as strings, return
# the product of num1 and num2, also represented as a string.
#
# Example 1:
#
# Input: num1 = "2", num2 = "3"
# Output: "6"
#
# Example 2:
#
# Input: num1 = "123", num2 = "456"
# Output: "56088"
#
#
# Note:
#
#
# The length of both num1 and num2 is < 110.
# Both num1 and num2 contain only digits 0-9.
# Both num1 and num2 do not contain any leading zero, except the number 0
# itself.
# You must not use any built-in BigInteger library or convert the inputs
# to integer directly.# Time: O(m * n)
# Space: O(m + n)
class Solution(object):
def multiply(self, num1, num2):
"""
:type num1: str
:type num2: str
:rtype: str
"""
num1, num2 = num1[::-1], num2[::-1]
res = [0] * (len(num1) + len(num2))
for i in xrange(len(num1)):
for j in xrange(len(num2)):
res[i + j] += int(num1[i]) * int(num2[j])
res[i + j + 1] += res[i + j] / 10
res[i + j] %= 10
# Time: O(m * n)
# Space: O(m + n)
# Using built-in bignum solution.
class Solution2(object):
def multiply(self, num1, num2):
"""
:type num1: str
:type num2: str
:rtype: str
"""
return str(int(num1) * int(num2))
514
515
circular-array-loop.py
# You are given a circular array nums of positive and negative integers. If a
# number k at an index is positive, then move forward k steps. Conversely, if it's
# negative (-k), move backward k steps. Since the array is circular, you may
# assume that the last element's next element is the first element, and the first
# element's previous element is the last element.
#
# Determine if there is a loop (or a cycle) in nums. A cycle must start and end
# at the same index and the cycle's length > 1. Furthermore, movements in a cycle
# must all follow a single direction. In other words, a cycle must not consist of
# both forward and backward movements.
#
#
#
# Example 1:
#
# Input: [2,-1,1,2,2]
# Output: true
# Explanation: There is a cycle, from index 0 -> 2 -> 3 -> 0. The cycle's length
# is 3.
#
#
# Example 2:
#
# Input: [-1,2]
# Output: false
# Explanation: The movement from index 1 -> 1 -> 1 ... is not a cycle, because
# the cycle's length is 1. By definition the cycle's length must be greater than
# 1.
#
#
# Example 3:
#
# Input: [-2,1,-1,-2,-2]
# Output: false
# Explanation: The movement from index 1 -> 2 -> 1 -> ... is not a cycle,
# because movement from index 1 -> 2 is a forward movement, but movement from
# index 2 -> 1 is a backward movement. All movements in a cycle must follow a
# single direction.
#
#
#
# Note:
#
#
# -1000 nums[i] 1000
# nums[i] 0
# 1 nums.length 5000
#
#
#
#
# Follow up:
#
# Could you solve it in O(n) time complexity and O(1) extra space complexity?# Time: O(n)
# Space: O(1)
class Solution(object):
def circularArrayLoop(self, nums):
516
"""
:type nums: List[int]
:rtype: bool
"""
def next_index(nums, i):
return (i + nums[i]) % len(nums)
for i in xrange(len(nums)):
if nums[i] == 0:
continue
slow, fast = i, i
while nums[next_index(nums, slow)] * nums[i] > 0 and \
nums[next_index(nums, fast)] * nums[i] > 0 and \
nums[next_index(nums, next_index(nums, fast))] * nums[i] > 0:
slow = next_index(nums, slow)
fast = next_index(nums, next_index(nums, fast))
if slow == fast:
if slow == next_index(nums, slow):
break
return True
return False
517
largest-1-bordered-square.py
# Given a 2D grid of 0s and 1s, return the number of elements in the largest
# square subgrid that has all 1s on its border, or 0 if such a subgrid doesn't
# exist in the grid.
#
#
# Example 1:
#
# Input: grid = [[1,1,1],[1,0,1],[1,1,1]]
# Output: 9
#
#
# Example 2:
#
# Input: grid = [[1,1,0,0]]
# Output: 1
#
#
#
# Constraints:
#
#
# 1 <= grid.length <= 100
# 1 <= grid[0].length <= 100
# grid[i][j] is 0 or 1# Time: O(n^3)
# Space: O(n^2)
class Solution(object):
def largest1BorderedSquare(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
top, left = [a[:] for a in grid], [a[:] for a in grid]
for i in xrange(len(grid)):
for j in xrange(len(grid[0])):
if not grid[i][j]:
continue
if i:
top[i][j] = top[i-1][j] + 1
if j:
left[i][j] = left[i][j-1] + 1
for l in reversed(xrange(1, min(len(grid), len(grid[0]))+1)):
for i in xrange(len(grid)-l+1):
for j in xrange(len(grid[0])-l+1):
if min(top[i+l-1][j],
top[i+l-1][j+l-1],
left[i][j+l-1],
left[i+l-1][j+l-1]) >= l:
return l*l
return 0
518
check-if-a-string-contains-all-binary-codes-of-size-k.py
# Given a binary string s and an integer k.
#
# Return True if every binary code of length k is a substring of s. Otherwise,
# return False.
#
#
# Example 1:
#
# Input: s = "00110110", k = 2
# Output: true
# Explanation: The binary codes of length 2 are "00", "01", "10" and "11". They
# can be all found as substrings at indicies 0, 1, 3 and 2 respectively.
#
#
# Example 2:
#
# Input: s = "00110", k = 2
# Output: true
#
#
# Example 3:
#
# Input: s = "0110", k = 1
# Output: true
# Explanation: The binary codes of length 1 are "0" and "1", it is clear that
# both exist as a substring.
#
#
# Example 4:
#
# Input: s = "0110", k = 2
# Output: false
# Explanation: The binary code "00" is of length 2 and doesn't exist in the
# array.
#
#
# Example 5:
#
# Input: s = "0000000001011100", k = 4
# Output: false
#
#
#
# Constraints:
#
#
# 1 <= s.length <= 5 * 10^5
# s consists of 0's and 1's only.
# 1 <= k <= 20# Time: O(n * k)
# Space: O(k * 2^k)
class Solution(object):
def hasAllCodes(self, s, k):
"""
:type s: str
:type k: int
:rtype: bool
"""
519
return 2**k <= len(s) and len({s[i:i+k] for i in xrange(len(s)-k+1)}) == 2**k
# Time: O(n * k)
# Space: O(2^k)
class Solution2(object):
def hasAllCodes(self, s, k):
"""
:type s: str
:type k: int
:rtype: bool
"""
lookup = set()
base = 2**k
if base > len(s):
return False
num = 0
for i in xrange(len(s)):
num = (num << 1) + (s[i] == '1')
if i >= k-1:
lookup.add(num)
num -= (s[i-k+1] == '1') * (base//2)
return len(lookup) == base
520
valid-sudoku.py
# Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be
# validated according to the following rules:
#
#
# Each row must contain the digits 1-9 without repetition.
# Each column must contain the digits 1-9 without repetition.
# Each of the 9 3x3 sub-boxes of the grid must contain the
# digits 1-9 without repetition.
#
#
#
#
# A partially filled sudoku which is valid.
#
# The Sudoku board could be partially filled, where empty cells are filled with
# the character '.'.
#
# Example 1:
#
# Input:
# [
# ["5","3",".",".","7",".",".",".","."],
# ["6",".",".","1","9","5",".",".","."],
# [".","9","8",".",".",".",".","6","."],
# ["8",".",".",".","6",".",".",".","3"],
# ["4",".",".","8",".","3",".",".","1"],
# ["7",".",".",".","2",".",".",".","6"],
# [".","6",".",".",".",".","2","8","."],
# [".",".",".","4","1","9",".",".","5"],
# [".",".",".",".","8",".",".","7","9"]
# ]
# Output: true
#
#
# Example 2:
#
# Input:
# [
# ["8","3",".",".","7",".",".",".","."],
# ["6",".",".","1","9","5",".",".","."],
# [".","9","8",".",".",".",".","6","."],
# ["8",".",".",".","6",".",".",".","3"],
# ["4",".",".","8",".","3",".",".","1"],
# ["7",".",".",".","2",".",".",".","6"],
# [".","6",".",".",".",".","2","8","."],
# [".",".",".","4","1","9",".",".","5"],
# [".",".",".",".","8",".",".","7","9"]
# ]
# Output: false
# Explanation: Same as Example 1, except with the 5 in the top left corner being
# modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is
# invalid.
#
#
# Note:
#
#
# A Sudoku board (partially filled) could be valid but is not necessarily
521
# solvable.
# Only the filled cells need to be validated according to the
# mentioned rules.
# The given board contain only digits 1-9 and the character '.'.
# The given board size is always 9x9.# Time: O(9^2)
# Space: O(9)
class Solution(object):
def isValidSudoku(self, board):
"""
:type board: List[List[str]]
:rtype: bool
"""
for i in xrange(9):
if not self.isValidList([board[i][j] for j in xrange(9)]) or \
not self.isValidList([board[j][i] for j in xrange(9)]):
return False
for i in xrange(3):
for j in xrange(3):
if not self.isValidList([board[m][n] for n in xrange(3 * j, 3 * j + 3) \
for m in xrange(3 * i, 3 * i + 3)]):
return False
return True
522
can-i-win.py
# In the "100 game" two players take turns adding, to a running total, any
# integer from 1 to 10. The player who first causes the running total to reach or
# exceed 100 wins.
#
# What if we change the game so that players cannot re-use integers?
#
# For example, two players might take turns drawing from a common pool of
# numbers from 1 to 15 without replacement until they reach a total >= 100.
#
# Given two integers maxChoosableInteger and desiredTotal, return true if the
# first player to move can force a win, otherwise return false. Assume both
# players play optimally.
#
#
# Example 1:
#
# Input: maxChoosableInteger = 10, desiredTotal = 11
# Output: false
# Explanation:
# No matter which integer the first player choose, the first player will lose.
# The first player can choose an integer from 1 up to 10.
# If the first player choose 1, the second player can only choose integers from
# 2 up to 10.
# The second player will win by choosing 10 and get a total = 11, which is >=
# desiredTotal.
# Same with other integers chosen by the first player, the second player will
# always win.
#
#
# Example 2:
#
# Input: maxChoosableInteger = 10, desiredTotal = 0
# Output: true
#
#
# Example 3:
#
# Input: maxChoosableInteger = 10, desiredTotal = 1
# Output: true
#
#
#
# Constraints:
#
#
# 1 <= maxChoosableInteger <= 20
# 0 <= desiredTotal <= 300# Time: O(n!)
# Space: O(n)
class Solution(object):
def canIWin(self, maxChoosableInteger, desiredTotal):
"""
:type maxChoosableInteger: int
:type desiredTotal: int
:rtype: bool
"""
def canIWinHelper(maxChoosableInteger, desiredTotal, visited, lookup):
if visited in lookup:
523
return lookup[visited]
mask = 1
for i in xrange(maxChoosableInteger):
if visited & mask == 0:
if i + 1 >= desiredTotal or \
not canIWinHelper(maxChoosableInteger, desiredTotal - (i + 1), visited | mask, lookup):
lookup[visited] = True
return True
mask <<= 1
lookup[visited] = False
return False
524
additive-number.py
# Additive number is a string whose digits can form additive sequence.
#
# A valid additive sequence should contain at least three numbers. Except for
# the first two numbers, each subsequent number in the sequence must be the sum of
# the preceding two.
#
# Given a string containing only digits '0'-'9', write a function to determine
# if it's an additive number.
#
# Note: Numbers in the additive sequence cannot have leading zeros, so sequence
# 1, 2, 03 or 1, 02, 3 is invalid.
#
#
# Example 1:
#
# Input: "112358"
# Output: true
# Explanation: The digits can form an additive sequence: 1, 1, 2, 3, 5, 8.
# 1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8
#
#
# Example 2:
#
# Input: "199100199"
# Output: true
# Explanation: The additive sequence is: 1, 99, 100, 199.
# 1 + 99 = 100, 99 + 100 = 199
#
#
#
# Constraints:
#
#
# num consists only of digits '0'-'9'.
# 1 <= num.length <= 35
#
#
# Follow up:
#
# How would you handle overflow for very large input integers?# Time: O(n^3)
# Space: O(n)
class Solution(object):
def isAdditiveNumber(self, num):
"""
:type num: str
:rtype: bool
"""
def add(a, b):
res, carry, val = "", 0, 0
for i in xrange(max(len(a), len(b))):
val = carry
if i < len(a):
val += int(a[-(i + 1)])
if i < len(b):
val += int(b[-(i + 1)])
carry, val = val / 10, val % 10
525
res += str(val)
if carry:
res += str(carry)
return res[::-1]
526
3sum.py
# Given an array nums of n integers, are there elements a, b, c in nums such
# that a + b + c = 0? Find all unique triplets in the array which gives the sum of
# zero.
#
# Note:
#
# The solution set must not contain duplicate triplets.
#
# Example:
#
# Given array nums = [-1, 0, 1, 2, -1, -4],
#
# A solution set is:
# [
# [-1, 0, 1],
# [-1, -1, 2]
# ]# Time: O(n^2)
# Space: O(1)
import collections
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums, result, i = sorted(nums), [], 0
while i < len(nums) - 2:
if i == 0 or nums[i] != nums[i - 1]:
j, k = i + 1, len(nums) - 1
while j < k:
if nums[i] + nums[j] + nums[k] < 0:
j += 1
elif nums[i] + nums[j] + nums[k] > 0:
k -= 1
else:
result.append([nums[i], nums[j], nums[k]])
j, k = j + 1, k - 1
while j < k and nums[j] == nums[j - 1]:
j += 1
while j < k and nums[k] == nums[k + 1]:
k -= 1
i += 1
return result
527
numss2 = nums_new[i + 1:]
for x, y in enumerate(numss2):
if 0 - j - y in [j, y] and 0 - j - y in nums_2:
if sorted([j, y, 0 - j - y]) not in rtn:
rtn.append(sorted([j, y, 0 - j - y]))
if 0 - j - y not in [j, y] and 0 - j - y in nums_new:
if sorted([j, y, 0 - j - y]) not in rtn:
rtn.append(sorted([j, y, 0 - j - y]))
return rtn
528
minimum-cost-tree-from-leaf-values.py
# Given an array arr of positive integers, consider all binary trees such that:
#
#
# Each node has either 0 or 2 children;
# The values of arr correspond to the values of each leaf in an in-order
# traversal of the tree. (Recall that a node is a leaf if and only if it has 0
# children.)
# The value of each non-leaf node is equal to the product of the largest
# leaf value in its left and right subtree respectively.
#
#
# Among all possible binary trees considered, return the smallest possible sum
# of the values of each non-leaf node. It is guaranteed this sum fits into a
# 32-bit integer.
#
#
# Example 1:
#
# Input: arr = [6,2,4]
# Output: 32
# Explanation:
# There are two possible trees. The first has non-leaf node sum 36, and the
# second has non-leaf node sum 32.
#
# 24 24
# / \ / \
# 12 4 6 8
# / \ / \
# 6 2 2 4
#
#
#
# Constraints:
#
#
# 2 <= arr.length <= 40
# 1 <= arr[i] <= 15
# It is guaranteed that the answer fits into a 32-bit signed integer
# (ie. it is less than 2^31).# Time: O(n)
# Space: O(n)
class Solution(object):
def mctFromLeafValues(self, arr):
"""
:type arr: List[int]
:rtype: int
"""
result = 0
stk = [float("inf")]
for x in arr:
while stk[-1] <= x:
result += stk.pop() * min(stk[-1], x)
stk.append(x)
while len(stk) > 2:
result += stk.pop() * stk[-1]
return result
529
longest-palindromic-subsequence.py
# Given a string s, find the longest palindromic subsequence's length in s. You
# may assume that the maximum length of s is 1000.
#
# Example 1:
#
# Input:
#
# "bbbab"
#
# Output:
#
# 4
#
# One possible longest palindromic subsequence is "bbbb".
#
#
#
# Example 2:
#
# Input:
#
# "cbbd"
#
# Output:
#
# 2
#
# One possible longest palindromic subsequence is "bb".
#
# Constraints:
#
#
# 1 <= s.length <= 1000
# s consists only of lowercase English letters.# Time: O(n^2)
# Space: O(n)
class Solution(object):
def longestPalindromeSubseq(self, s):
"""
:type s: str
:rtype: int
"""
if s == s[::-1]: # optional, to optimize special case
return len(s)
530
closest-divisors.py
# Given an integer num, find the closest two integers in absolute difference
# whose product equals num + 1 or num + 2.
#
# Return the two integers in any order.
#
#
# Example 1:
#
# Input: num = 8
# Output: [3,3]
# Explanation: For num + 1 = 9, the closest divisors are 3 & 3, for num + 2 =
# 10, the closest divisors are 2 & 5, hence 3 & 3 is chosen.
#
#
# Example 2:
#
# Input: num = 123
# Output: [5,25]
#
#
# Example 3:
#
# Input: num = 999
# Output: [40,25]
#
#
#
# Constraints:
#
#
# 1 <= num <= 10^9# Time: O(sqrt(n))
# Space: O(1)
class Solution(object):
def closestDivisors(self, num):
"""
:type num: int
:rtype: List[int]
"""
def divisors(n):
for d in reversed(xrange(1, int(n**0.5)+1)):
if n % d == 0:
return d, n//d
return 1, n
# Time: O(sqrt(n))
# Space: O(1)
class Solution2(object):
def closestDivisors(self, num):
"""
:type num: int
:rtype: List[int]
"""
result, d = [1, num+1], 1
531
while d*d <= num+2:
if (num+2) % d == 0:
result = [d, (num+2)//d]
if (num+1) % d == 0:
result = [d, (num+1)//d]
d += 1
return result
532
minimum-moves-to-equal-array-elements-ii.py
# Given a non-empty integer array, find the minimum number of moves required to
# make all array elements equal, where a move is incrementing a selected element
# by 1 or decrementing a selected element by 1.
#
# You may assume the array's length is at most 10,000.
#
# Example:
# Input:
# [1,2,3]
#
# Output:
# 2
#
# Explanation:
# Only two moves are needed (remember each move increments or decrements one
# element):
#
# [1,2,3] => [2,2,3] => [2,2,2]# Time: O(n) on average
# Space: O(1)
533
:type nums: List[int]
:rtype: int
"""
median = sorted(nums)[len(nums) / 2]
return sum(abs(num - median) for num in nums)
534
smallest-subsequence-of-distinct-characters.py
# Return the lexicographically smallest subsequence of text that contains all
# the distinct characters of text exactly once.
#
# Example 1:
#
# Input: "cdadabcc"
# Output: "adbc"
#
#
#
# Example 2:
#
# Input: "abcd"
# Output: "abcd"
#
#
#
# Example 3:
#
# Input: "ecbacba"
# Output: "eacb"
#
#
#
# Example 4:
#
# Input: "leetcode"
# Output: "letcod"
#
#
#
#
# Constraints:
#
#
# 1 <= text.length <= 1000
# text consists of lowercase English letters.
#
#
# Note: This question is the same as 316: https://leetcode.com/problems/remove-
# duplicate-letters/# Time: O(n)
# Space: O(1)
import collections
class Solution(object):
def smallestSubsequence(self, text):
"""
:type text: str
:rtype: str
"""
count = collections.Counter(text)
535
lookup.remove(stk.pop())
stk += c
lookup.add(c)
count[c] -= 1
return "".join(stk)
536
find-bottom-left-tree-value.py
# Given a binary tree, find the leftmost value in the last row of the tree.
#
#
# Example 1:
#
# Input:
#
# 2
# / \
# 1 3
#
# Output:
# 1
#
#
#
# Example 2:
#
# Input:
#
# 1
# / \
# 2 3
# / / \
# 4 5 6
# /
# 7
#
# Output:
# 7
#
#
#
# Note:
# You may assume the tree (i.e., the given root node) is not NULL.# Time: O(n)
# Space: O(h)
class Solution(object):
def findBottomLeftValue(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def findBottomLeftValueHelper(root, curr_depth, max_depth, bottom_left_value):
if not root:
return max_depth, bottom_left_value
if not root.left and not root.right and curr_depth+1 > max_depth:
return curr_depth+1, root.val
max_depth, bottom_left_value = findBottomLeftValueHelper(root.left, curr_depth+1, max_depth, bottom
max_depth, bottom_left_value = findBottomLeftValueHelper(root.right, curr_depth+1, max_depth, botto
return max_depth, bottom_left_value
result, max_depth = 0, 0
return findBottomLeftValueHelper(root, 0, max_depth, result)[1]
# Time: O(n)
# Space: O(n)
537
class Solution2(object):
def findBottomLeftValue(self, root):
"""
:type root: TreeNode
:rtype: int
"""
last_node, queue = None, [root]
while queue:
last_node = queue.pop(0)
queue.extend([n for n in [last_node.right, last_node.left] if n])
return last_node.value
538
combinations.py
# Given two integers n and k, return all possible combinations of k numbers out
# of 1 ... n.
#
# You may return the answer in any order.
#
#
# Example 1:
#
# Input: n = 4, k = 2
# Output:
# [
# [2,4],
# [3,4],
# [2,3],
# [1,2],
# [1,3],
# [1,4],
# ]
#
#
# Example 2:
#
# Input: n = 1, k = 1
# Output: [[1]]
#
#
#
# Constraints:
#
#
# 1 <= n <= 20
# 1 <= k <= n# Time: O(k * C(n, k))
# Space: O(k)
class Solution(object):
def combine(self, n, k):
"""
:type n: int
:type k: int
:rtype: List[List[int]]
"""
if k > n:
return []
nums, idxs = range(1, n+1), range(k)
result = [[nums[i] for i in idxs]]
while True:
for i in reversed(xrange(k)):
if idxs[i] != i+n-k:
break
else:
break
idxs[i] += 1
for j in xrange(i+1, k):
idxs[j] = idxs[j-1]+1
result.append([nums[i] for i in idxs])
return result
539
# Time: O(k * C(n, k))
# Space: O(k)
class Solution2(object):
def combine(self, n, k):
"""
:type n: int
:type k: int
:rtype: List[List[int]]
"""
result, combination = [], []
i = 1
while True:
if len(combination) == k:
result.append(combination[:])
if len(combination) == k or \
len(combination)+(n-i+1) < k:
if not combination:
break
i = combination.pop()+1
else:
combination.append(i)
i += 1
return result
result = []
combineDFS(n, 0, [], k, result)
return result
540
capacity-to-ship-packages-within-d-days.py
# A conveyor belt has packages that must be shipped from one port to another
# within D days.
#
# The i-th package on the conveyor belt has a weight of weights[i]. Each day,
# we load the ship with packages on the conveyor belt (in the order given by
# weights). We may not load more weight than the maximum weight capacity of the
# ship.
#
# Return the least weight capacity of the ship that will result in all the
# packages on the conveyor belt being shipped within D days.
#
#
#
# Example 1:
#
# Input: weights = [1,2,3,4,5,6,7,8,9,10], D = 5
# Output: 15
# Explanation:
# A ship capacity of 15 is the minimum to ship all the packages in 5 days like
# this:
# 1st day: 1, 2, 3, 4, 5
# 2nd day: 6, 7
# 3rd day: 8
# 4th day: 9
# 5th day: 10
#
# Note that the cargo must be shipped in the order given, so using a ship of
# capacity 14 and splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7),
# (8), (9), (10) is not allowed.
#
#
# Example 2:
#
# Input: weights = [3,2,2,4,1,4], D = 3
# Output: 6
# Explanation:
# A ship capacity of 6 is the minimum to ship all the packages in 3 days like
# this:
# 1st day: 3, 2
# 2nd day: 2, 4
# 3rd day: 1, 4
#
#
# Example 3:
#
# Input: weights = [1,2,3,1,1], D = 4
# Output: 3
# Explanation:
# 1st day: 1
# 2nd day: 2
# 3rd day: 3
# 4th day: 1, 1
#
#
#
# Constraints:
#
#
541
# 1 <= D <= weights.length <= 50000
# 1 <= weights[i] <= 500# Time: O(nlogr)
# Space: O(1)
class Solution(object):
def shipWithinDays(self, weights, D):
"""
:type weights: List[int]
:type D: int
:rtype: int
"""
def possible(weights, D, mid):
result, curr = 1, 0
for w in weights:
if curr+w > mid:
result += 1
curr = 0
curr += w
return result <= D
542
game-of-life.py
# According to the Wikipedia's article: "The Game of Life, also known simply as
# Life, is a cellular automaton devised by the British mathematician John Horton
# Conway in 1970."
#
# Given a board with m by n cells, each cell has an initial state live (1) or
# dead (0). Each cell interacts with its eight neighbors (horizontal, vertical,
# diagonal) using the following four rules (taken from the above Wikipedia
# article):
#
#
# Any live cell with fewer than two live neighbors dies, as if caused by
# under-population.
# Any live cell with two or three live neighbors lives on to the next
# generation.
# Any live cell with more than three live neighbors dies, as if by over-
# population..
# Any dead cell with exactly three live neighbors becomes a live cell, as
# if by reproduction.
#
#
# Write a function to compute the next state (after one update) of the board
# given its current state. The next state is created by applying the above rules
# simultaneously to every cell in the current state, where births and deaths occur
# simultaneously.
#
# Example:
#
# Input:
# [
# [0,1,0],
# [0,0,1],
# [1,1,1],
# [0,0,0]
# ]
# Output:
# [
# [0,0,0],
# [1,0,1],
# [0,1,1],
# [0,1,0]
# ]
#
#
# Follow up:
#
#
# Could you solve it in-place? Remember that the board needs to be updated
# at the same time: You cannot update some cells first and then use their updated
# values to update other cells.
# In this question, we represent the board using a 2D array. In principle,
# the board is infinite, which would cause problems when the active area
# encroaches the border of the array. How would you address these problems?# Time: O(m * n)
# Space: O(1)
class Solution(object):
def gameOfLife(self, board):
"""
:type board: List[List[int]]
543
:rtype: void Do not return anything, modify board in-place instead.
"""
m = len(board)
n = len(board[0]) if m else 0
for i in xrange(m):
for j in xrange(n):
count = 0
## Count live cells in 3x3 block.
for I in xrange(max(i-1, 0), min(i+2, m)):
for J in xrange(max(j-1, 0), min(j+2, n)):
count += board[I][J] & 1
for i in xrange(m):
for j in xrange(n):
board[i][j] >>= 1 # Update to the next state.
544
online-stock-span.py
# Example 1:
#
# Input: ["StockSpanner","next","next","next","next","next","next","next"],
# [[],[100],[80],[60],[70],[60],[75],[85]]
# Output: [null,1,1,1,2,1,4,6]
# Explanation:
# First, S = StockSpanner() is initialized. Then:
# S.next(100) is called and returns 1,
# S.next(80) is called and returns 1,
# S.next(60) is called and returns 1,
# S.next(70) is called and returns 2,
# S.next(60) is called and returns 1,
# S.next(75) is called and returns 4,
# S.next(85) is called and returns 6.
#
# Note that (for example) S.next(75) returned 4, because the last 4 prices
# (including today's price of 75) were less than or equal to today's price.
#
#
#
#
# Note:
#
#
# Calls to StockSpanner.next(int price) will have 1 <= price <= 10^5.
# There will be at most 10000 calls to StockSpanner.next per test case.
# There will be at most 150000 calls to StockSpanner.next across all test
# cases.
# The total time limit for this problem has been reduced by 75% for C++,
# and 50% for all other languages.# Time: O(n)
# Space: O(n)
class StockSpanner(object):
def __init__(self):
self.__s = []
545
interval-list-intersections.py
# Given two lists of closed intervals, each list of intervals is pairwise
# disjoint and in sorted order.
#
# Return the intersection of these two interval lists.
#
# (Formally, a closed interval [a, b] (with a <= b) denotes the set of real
# numbers x with a <= x <= b. The intersection of two closed intervals is a set
# of real numbers that is either empty, or can be represented as a closed
# interval. For example, the intersection of [1, 3] and [2, 4] is [2, 3].)
#
#
#
#
# Example 1:
#
#
#
# Input: A = [[0,2],[5,10],[13,23],[24,25]], B = [[1,5],[8,12],[15,24],[25,26]]
# Output: [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]
#
#
#
#
# Note:
#
#
# 0 <= A.length < 1000
# 0 <= B.length < 1000
# 0 <= A[i].start, A[i].end, B[i].start, B[i].end < 10^9# Time: O(m + n)
# Space: O(1)
class Solution(object):
def intervalIntersection(self, A, B):
"""
:type A: List[Interval]
:type B: List[Interval]
:rtype: List[Interval]
"""
result = []
i, j = 0, 0
while i < len(A) and j < len(B):
left = max(A[i].start, B[j].start)
right = min(A[i].end, B[j].end)
if left <= right:
result.append(Interval(left, right))
if A[i].end < B[j].end:
i += 1
else:
j += 1
return result
546
lexicographical-numbers.py
# Given an integer n, return 1 - n in lexicographical order.
#
# For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9].
#
# Please optimize your algorithm to use less time and space. The input size may
# be as large as 5,000,000.# Time: O(n)
# Space: O(1)
class Solution(object):
def lexicalOrder(self, n):
result = []
i = 1
while len(result) < n:
k = 0
while i * 10**k <= n:
result.append(i * 10**k)
k += 1
num = result[-1] + 1
while num <= n and num % 10:
result.append(num)
num += 1
while num % 10 == 9:
num /= 10
i = num+1
return result
547
most-frequent-subtree-sum.py
# Given the root of a tree, you are asked to find the most frequent subtree sum.
# The subtree sum of a node is defined as the sum of all the node values formed by
# the subtree rooted at that node (including the node itself). So what is the most
# frequent subtree sum value? If there is a tie, return all the values with the
# highest frequency in any order.
#
#
# Examples 1
#
# Input:
# 5
# / \
# 2 -3
#
# return [2, -3, 4], since all the values happen only once, return all of them
# in any order.
#
#
# Examples 2
#
# Input:
# 5
# / \
# 2 -5
#
# return [2], since 2 happens twice, however -5 only occur once.
#
#
# Note:
# You may assume the sum of values in any subtree is in the range of 32-bit
# signed integer.# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def findFrequentTreeSum(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
def countSubtreeSumHelper(root, counts):
if not root:
return 0
total = root.val + \
countSubtreeSumHelper(root.left, counts) + \
countSubtreeSumHelper(root.right, counts)
counts[total] += 1
return total
counts = collections.defaultdict(int)
countSubtreeSumHelper(root, counts)
max_count = max(counts.values()) if counts else 0
return [total for total, count in counts.iteritems() if count == max_count]
548
k-closest-points-to-origin.py
# Example 1:
#
# Input: points = [[1,3],[-2,2]], K = 1
# Output: [[-2,2]]
# Explanation:
# The distance between (1, 3) and the origin is sqrt(10).
# The distance between (-2, 2) and the origin is sqrt(8).
# Since sqrt(8) < sqrt(10), (-2, 2) is closer to the origin.
# We only want the closest K = 1 points from the origin, so the answer is just
# [[-2,2]].
#
#
#
# Example 2:
#
# Input: points = [[3,3],[5,-1],[-2,4]], K = 2
# Output: [[3,3],[-2,4]]
# (The answer [[-2,4],[3,3]] would also be accepted.)
#
#
#
#
# Note:
#
#
# 1 <= K <= points.length <= 10000
# -10000 < points[i][0] < 10000
# -10000 < points[i][1] < 10000# Time: O(n) on average
# Space: O(1)
class Solution(object):
def kClosest(self, points, K):
"""
:type points: List[List[int]]
:type K: int
:rtype: List[List[int]]
"""
def dist(point):
return point[0]**2 + point[1]**2
549
pivot_idx = randint(left, right)
new_pivot_idx = PartitionAroundPivot(left, right, pivot_idx, nums, compare)
if new_pivot_idx == k:
return
elif new_pivot_idx > k:
right = new_pivot_idx - 1
else: # new_pivot_idx < k.
left = new_pivot_idx + 1
# Time: O(nlogk)
# Space: O(k)
import heapq
class Solution2(object):
def kClosest(self, points, K):
"""
:type points: List[List[int]]
:type K: int
:rtype: List[List[int]]
"""
def dist(point):
return point[0]**2 + point[1]**2
max_heap = []
for point in points:
heapq.heappush(max_heap, (-dist(point), point))
if len(max_heap) > K:
heapq.heappop(max_heap)
return [heapq.heappop(max_heap)[1] for _ in xrange(len(max_heap))]
550
implement-magic-dictionary.py
# Design a data structure which is initialized with a list of different words.
# After that, we will give you a string, and you should find out if you can change
# exactly one character in this string to match any word in the data structure.
#
# Implement the MagicDictionary class:
#
#
# MagicDictionary() Initializes the object.
# void buildDict(String[] dictionary) Sets the data structure with an
# array of distinct strings dictionary.
# bool search(String searchWord) Returns true if you can change exactly
# one character in word to match any string in the data structure, otherwise
# returns false.
#
#
#
# Example 1:
#
# Input
# ["MagicDictionary", "buildDict", "search", "search", "search", "search"]
# [[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]]
# Output
# [null, null, false, true, false, false]
#
# Explanation
# MagicDictionary magicDictionary = new MagicDictionary();
# magicDictionary.buildDict(["hello", "leetcode"]);
# magicDictionary.search("hello"); // return False
# magicDictionary.search("hhllo"); // We can change the second 'h' to 'e' to
# match "hello" so we return True
# magicDictionary.search("hell"); // return False
# magicDictionary.search("leetcoded"); // return False
#
#
#
# Constraints:
#
#
# 1 <= dictionary.length <= 100
# 1 <= dictionary[i],length <= 100
# dictionary[i] consist of only lower-case English letters.
# All the strings in dictionary are distinct.
# 1 <= searchWord.length <= 100
# searchWord consist of only lower-case English letters.
# buildDict will be called only one time.
# At most 100 calls will be made to search,# Time: O(n), n is the length of the word
# Space: O(d)
import collections
class MagicDictionary(object):
def __init__(self):
"""
Initialize your data structure here.
"""
_trie = lambda: collections.defaultdict(_trie)
551
self.trie = _trie()
if mistakeAllowed:
return find(word, curr[word[i]], i+1, True) or \
any(find(word, curr[c], i+1, False) \
for c in curr if c not in ("_end", word[i]))
return find(word, curr[word[i]], i+1, False)
552
h-index.py
# Given an array of citations (each citation is a non-negative integer) of a
# researcher, write a function to compute the researcher's h-index.
#
# According to the definition of h-index on Wikipedia: "A scientist has index h
# if h of his/her N papers have at least h citations each, and the other N h
# papers have no more than h citations each."
#
# Example:
#
# Input: citations = [3,0,6,1,5]
# Output: 3
# Explanation: [3,0,6,1,5] means the researcher has 5 papers in total and each
# of them had
# received 3, 0, 6, 1, 5 citations respectively.
# Since the researcher has 3 papers with at least 3 citations each
# and the remaining
# two with no more than 3 citations each, her h-index is 3.
#
# Note: If there are several possible values for h, the maximum one is taken as
# the h-index.# Time: O(n)
# Space: O(n)
class Solution(object):
def hIndex(self, citations):
"""
:type citations: List[int]
:rtype: int
"""
n = len(citations)
count = [0] * (n + 1)
for x in citations:
# Put all x >= n in the same bucket.
if x >= n:
count[n] += 1
else:
count[x] += 1
h = 0
for i in reversed(xrange(0, n + 1)):
h += count[i]
if h >= i:
return i
return h
# Time: O(nlogn)
# Space: O(1)
class Solution2(object):
def hIndex(self, citations):
"""
:type citations: List[int]
:rtype: int
"""
citations.sort(reverse=True)
h = 0
for x in citations:
if x >= h + 1:
h += 1
else:
553
break
return h
# Time: O(nlogn)
# Space: O(n)
class Solution3(object):
def hIndex(self, citations):
"""
:type citations: List[int]
:rtype: int
"""
return sum(x >= i + 1 for i, x in enumerate(sorted(citations, reverse=True)))
554
construct-binary-tree-from-preorder-and-postorder-traversal.py
# Example 1:
#
# Input: pre = [1,2,4,5,3,6,7], post = [4,5,2,6,7,3,1]
# Output: [1,2,3,4,5,6,7]
#
#
#
#
# Note:
#
#
# 1 <= pre.length == post.length <= 30
# pre[] and post[] are both permutations of 1, 2, ..., pre.length.
# It is guaranteed an answer exists. If there exists multiple answers, you
# can return any of them.# Time: O(n)
# Space: O(h)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution(object):
def constructFromPrePost(self, pre, post):
"""
:type pre: List[int]
:type post: List[int]
:rtype: TreeNode
"""
stack = [TreeNode(pre[0])]
j = 0
for i in xrange(1, len(pre)):
node = TreeNode(pre[i])
while stack[-1].val == post[j]:
stack.pop()
j += 1
if not stack[-1].left:
stack[-1].left = node
else:
stack[-1].right = node
stack.append(node)
return stack[0]
# Time: O(n)
# Space: O(n)
class Solution2(object):
def constructFromPrePost(self, pre, post):
"""
:type pre: List[int]
:type post: List[int]
:rtype: TreeNode
"""
def constructFromPrePostHelper(pre, pre_s, pre_e, post, post_s, post_e, post_entry_idx_map):
if pre_s >= pre_e or post_s >= post_e:
return None
555
node = TreeNode(pre[pre_s])
if pre_e-pre_s > 1:
left_tree_size = post_entry_idx_map[pre[pre_s+1]]-post_s+1
node.left = constructFromPrePostHelper(pre, pre_s+1, pre_s+1+left_tree_size,
post, post_s, post_s+left_tree_size,
post_entry_idx_map)
node.right = constructFromPrePostHelper(pre, pre_s+1+left_tree_size, pre_e,
post, post_s+left_tree_size, post_e-1,
post_entry_idx_map)
return node
post_entry_idx_map = {}
for i, val in enumerate(post):
post_entry_idx_map[val] = i
return constructFromPrePostHelper(pre, 0, len(pre), post, 0, len(post), post_entry_idx_map)
556
integer-break.py
# Example 2:
#
# Input: 10
# Output: 36
# Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.
#
# Note: You may assume that n is not less than 2 and not larger than 58.# Time: O(logn), pow is O(logn).
# Space: O(1)
class Solution(object):
def integerBreak(self, n):
"""
:type n: int
:rtype: int
"""
if n < 4:
return n - 1
# Proof.
# 1. Let n = a1 + a2 + ... + ak, product = a1 * a2 * ... * ak
# - For each ai >= 4, we can always maximize the product by:
# ai <= 2 * (ai - 2)
# - For each aj >= 5, we can always maximize the product by:
# aj <= 3 * (aj - 3)
#
# Conclusion 1:
# - For n >= 4, the max of the product must be in the form of
# 3^a * 2^b, s.t. 3a + 2b = n
#
# 2. To maximize the product = 3^a * 2^b s.t. 3a + 2b = n
# - For each b >= 3, we can always maximize the product by:
# 3^a * 2^b <= 3^(a+2) * 2^(b-3) s.t. 3(a+2) + 2(b-3) = n
#
# Conclusion 2:
# - For n >= 4, the max of the product must be in the form of
# 3^Q * 2^R, 0 <= R < 3 s.t. 3Q + 2R = n
# i.e.
# if n = 3Q + 0, the max of the product = 3^Q * 2^0
# if n = 3Q + 2, the max of the product = 3^Q * 2^1
# if n = 3Q + 2*2, the max of the product = 3^Q * 2^2
res = 0
if n % 3 == 0: # n = 3Q + 0, the max is 3^Q * 2^0
res = 3 ** (n // 3)
elif n % 3 == 2: # n = 3Q + 2, the max is 3^Q * 2^1
res = 3 ** (n // 3) * 2
else: # n = 3Q + 4, the max is 3^Q * 2^2
res = 3 ** (n // 3 - 1) * 4
return res
# Time: O(n)
# Space: O(1)
# DP solution.
class Solution2(object):
def integerBreak(self, n):
"""
:type n: int
557
:rtype: int
"""
if n < 4:
return n - 1
558
predict-the-winner.py
# Given an array of scores that are non-negative integers. Player 1 picks one of
# the numbers from either end of the array followed by the player 2 and then
# player 1 and so on. Each time a player picks a number, that number will not be
# available for the next player. This continues until all the scores have been
# chosen. The player with the maximum score wins.
#
# Given an array of scores, predict whether player 1 is the winner. You can
# assume each player plays to maximize his score.
#
# Example 1:
#
# Input: [1, 5, 2]
# Output: False
# Explanation: Initially, player 1 can choose between 1 and 2.
# If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If
# player 2 chooses 5, then player 1 will be left with 1 (or 2).
# So, final score of player 1 is 1 + 2 = 3, and player 2 is 5.
# Hence, player 1 will never be the winner and you need to return False.
#
#
#
#
# Example 2:
#
# Input: [1, 5, 233, 7]
# Output: True
# Explanation: Player 1 first chooses 1. Then player 2 have to choose between 5
# and 7. No matter which number player 2 choose, player 1 can choose 233.
# Finally, player 1 has more score (234) than player 2 (12), so you need to
# return True representing player1 can win.
#
#
#
# Constraints:
#
#
# 1 <= length of the array <= 20.
# Any scores in the given array are non-negative integers and will not
# exceed 10,000,000.
# If the scores of both players are equal, then player 1 is still the
# winner.# Time: O(n^2)
# Space: O(n)
class Solution(object):
def PredictTheWinner(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
if len(nums) % 2 == 0 or len(nums) == 1:
return True
dp = [0] * len(nums)
for i in reversed(xrange(len(nums))):
dp[i] = nums[i]
for j in xrange(i+1, len(nums)):
dp[j] = max(nums[i] - dp[j], nums[j] - dp[j - 1])
559
return dp[-1] >= 0
560
remove-covered-intervals.py
# Given a list of intervals, remove all intervals that are covered by another
# interval in the list. Interval [a,b) is covered by interval [c,d) if and only if
# c <= a and b <= d.
#
# After doing so, return the number of remaining intervals.
#
#
# Example 1:
#
# Input: intervals = [[1,4],[3,6],[2,8]]
# Output: 2
# Explanation: Interval [3,6] is covered by [2,8], therefore it is removed.
#
#
#
# Constraints:
#
#
# 1 <= intervals.length <= 1000
# 0 <= intervals[i][0] < intervals[i][1] <= 10^5
# intervals[i] != intervals[j] for all i != j# Time: O(nlogn)
# Space: O(1)
class Solution(object):
def removeCoveredIntervals(self, intervals):
"""
:type intervals: List[List[int]]
:rtype: int
"""
intervals.sort(key=lambda x: [x[0], -x[1]])
result, max_right = 0, 0
for left, right in intervals:
result += int(right > max_right)
max_right = max(max_right, right)
return result
561
find-peak-element.py
# A peak element is an element that is greater than its neighbors.
#
# Given an input array nums, where nums[i] nums[i+1], find a peak element and
# return its index.
#
# The array may contain multiple peaks, in that case return the index to any one
# of the peaks is fine.
#
# You may imagine that nums[-1] = nums[n] = -.
#
# Example 1:
#
# Input: nums = [1,2,3,1]
# Output: 2
# Explanation: 3 is a peak element and your function should return the index
# number 2.
#
# Example 2:
#
# Input: nums = [1,2,1,3,5,6,4]
# Output: 1 or 5
# Explanation: Your function can return either index number 1 where the peak
# element is 2,
# or index number 5 where the peak element is 6.
#
#
# Follow up: Your solution should be in logarithmic complexity.# Time: O(logn)
# Space: O(1)
class Solution(object):
def findPeakElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left, right = 0, len(nums) - 1
return left
562
reorder-list.py
# Given a singly linked list L: L0→L1→...→Ln-1→Ln,
#
# reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→...
#
# You may not modify the values in the list's nodes, only nodes itself may be
# changed.
#
# Example 1:
#
# Given 1->2->3->4, reorder it to 1->4->2->3.
#
# Example 2:
#
# Given 1->2->3->4->5, reorder it to 1->5->2->4->3.# Time: O(n)
# Space: O(1)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{} -> {}".format(self.val, repr(self.next))
class Solution(object):
# @param head, a ListNode
# @return nothing
def reorderList(self, head):
if head == None or head.next == None:
return head
return dummy.next
563
maximum-length-of-pair-chain.py
# You are given n pairs of numbers. In every pair, the first number is always
# smaller than the second number.
#
#
#
# Now, we define a pair (c, d) can follow another pair (a, b) if and only if b <
# c. Chain of pairs can be formed in this fashion.
#
#
#
# Given a set of pairs, find the length longest chain which can be formed. You
# needn't use up all the given pairs. You can select pairs in any order.
#
#
#
# Example 1:
#
# Input: [[1,2], [2,3], [3,4]]
# Output: 2
# Explanation: The longest chain is [1,2] -> [3,4]
#
#
#
# Note:
#
#
# The number of given pairs will be in the range [1, 1000].# Time: O(nlogn)
# Space: O(1)
class Solution(object):
def findLongestChain(self, pairs):
"""
:type pairs: List[List[int]]
:rtype: int
"""
pairs.sort(key=lambda x: x[1])
cnt, i = 0, 0
for j in xrange(len(pairs)):
if j == 0 or pairs[i][1] < pairs[j][0]:
cnt += 1
i = j
return cnt
564
integer-to-roman.py
# Roman numerals are represented by seven different symbols: I, V, X, L, C, D
# and M.
#
# Symbol Value
# I 1
# V 5
# X 10
# L 50
# C 100
# D 500
# M 1000
#
# For example, two is written as II in Roman numeral, just two one's added
# together. Twelve is written as, XII, which is simply X + II. The number twenty
# seven is written as XXVII, which is XX + V + II.
#
# Roman numerals are usually written largest to smallest from left to right.
# However, the numeral for four is not IIII. Instead, the number four is written
# as IV. Because the one is before the five we subtract it making four. The same
# principle applies to the number nine, which is written as IX. There are six
# instances where subtraction is used:
#
#
# I can be placed before V (5) and X (10) to make 4 and 9.
# X can be placed before L (50) and C (100) to make 40 and 90.
# C can be placed before D (500) and M (1000) to make 400 and 900.
#
#
# Given an integer, convert it to a roman numeral. Input is guaranteed to be
# within the range from 1 to 3999.
#
# Example 1:
#
# Input: 3
# Output: "III"
#
# Example 2:
#
# Input: 4
# Output: "IV"
#
# Example 3:
#
# Input: 9
# Output: "IX"
#
# Example 4:
#
# Input: 58
# Output: "LVIII"
# Explanation: L = 50, V = 5, III = 3.
#
#
# Example 5:
#
# Input: 1994
# Output: "MCMXCIV"
# Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.# Time: O(n)
565
# Space: O(1)
class Solution(object):
def intToRoman(self, num):
"""
:type num: int
:rtype: str
"""
numeral_map = {1: "I", 4: "IV", 5: "V", 9: "IX", \
10: "X", 40: "XL", 50: "L", 90: "XC", \
100: "C", 400: "CD", 500: "D", 900: "CM", \
1000: "M"}
keyset, result = sorted(numeral_map.keys()), []
return "".join(result)
566
rotting-oranges.py
# Example 1:
#
#
#
# Input: [[2,1,1],[1,1,0],[0,1,1]]
# Output: 4
#
#
#
# Example 2:
#
# Input: [[2,1,1],[0,1,1],[1,0,1]]
# Output: -1
# Explanation: The orange in the bottom left corner (row 2, column 0) is never
# rotten, because rotting only happens 4-directionally.
#
#
#
# Example 3:
#
# Input: [[0,2]]
# Output: 0
# Explanation: Since there are already no fresh oranges at minute 0, the answer
# is just 0.
#
#
#
#
# Note:
#
#
# 1 <= grid.length <= 10
# 1 <= grid[0].length <= 10
# grid[i][j] is only 0, 1, or 2.# Time: O(m * n)
# Space: O(m * n)
import collections
class Solution(object):
def orangesRotting(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
count = 0
q = collections.deque()
for r, row in enumerate(grid):
for c, val in enumerate(row):
if val == 2:
q.append((r, c, 0))
elif val == 1:
count += 1
result = 0
while q:
567
r, c, result = q.popleft()
for d in directions:
nr, nc = r+d[0], c+d[1]
if not (0 <= nr < len(grid) and \
0 <= nc < len(grid[r])):
continue
if grid[nr][nc] == 1:
count -= 1
grid[nr][nc] = 2
q.append((nr, nc, result+1))
return result if count == 0 else -1
568
snapshot-array.py
# Implement a SnapshotArray that supports the following interface:
#
#
# SnapshotArray(int length) initializes an array-like data structure with
# the given length. Initially, each element equals 0.
# void set(index, val) sets the element at the given index to be equal to
# val.
# int snap() takes a snapshot of the array and returns the snap_id: the
# total number of times we called snap() minus 1.
# int get(index, snap_id) returns the value at the given index, at the
# time we took the snapshot with the given snap_id
#
#
#
# Example 1:
#
# Input: ["SnapshotArray","set","snap","set","get"]
# [[3],[0,5],[],[0,6],[0,0]]
# Output: [null,null,0,null,5]
# Explanation:
# SnapshotArray snapshotArr = new SnapshotArray(3); // set the length to be 3
# snapshotArr.set(0,5); // Set array[0] = 5
# snapshotArr.snap(); // Take a snapshot, return snap_id = 0
# snapshotArr.set(0,6);
# snapshotArr.get(0,0); // Get the value of array[0] with snap_id = 0, return 5
#
#
# Constraints:
#
#
# 1 <= length <= 50000
# At most 50000 calls will be made to set, snap, and get.
# 0 <= index < length
# 0 <= snap_id < (the total number of times we call snap())
# 0 <= val <= 10^9# Time: set: O(1)
# get: O(logn), n is the total number of set
# Space: O(n)
import collections
import bisect
class SnapshotArray(object):
569
self.__A[index].append((self.__snap_id, val))
def snap(self):
"""
:rtype: int
"""
self.__snap_id += 1
return self.__snap_id - 1
570
longest-word-in-dictionary-through-deleting.py
# Given a string and a string dictionary, find the longest string in the
# dictionary that can be formed by deleting some characters of the given string.
# If there are more than one possible results, return the longest word with the
# smallest lexicographical order. If there is no possible result, return the empty
# string.
#
# Example 1:
#
# Input:
# s = "abpcplea", d = ["ale","apple","monkey","plea"]
#
# Output:
# "apple"
#
#
#
#
# Example 2:
#
# Input:
# s = "abpcplea", d = ["a","b","c"]
#
# Output:
# "a"
#
#
#
# Note:
#
#
# All the strings in the input will only contain lower-case letters.
# The size of the dictionary won't exceed 1,000.
# The length of all the strings in the input won't exceed 1,000.# Time: O((d * l) * logd), l is the average le
# Space: O(1)
class Solution(object):
def findLongestWord(self, s, d):
"""
:type s: str
:type d: List[str]
:rtype: str
"""
d.sort(key = lambda x: (-len(x), x))
for word in d:
i = 0
for c in s:
if i < len(word) and word[i] == c:
i += 1
if i == len(word):
return word
return ""
571
reconstruct-itinerary.py
# Given a list of airline tickets represented by pairs of departure and arrival
# airports [from, to], reconstruct the itinerary in order. All of the tickets
# belong to a man who departs from JFK. Thus, the itinerary must begin with JFK.
#
# Note:
#
#
# If there are multiple valid itineraries, you should return the itinerary
# that has the smallest lexical order when read as a single string. For example,
# the itinerary ["JFK", "LGA"] has a smaller lexical order than ["JFK", "LGB"].
# All airports are represented by three capital letters (IATA code).
# You may assume all tickets form at least one valid itinerary.
# One must use all the tickets once and only once.
#
#
# Example 1:
#
# Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
# Output: ["JFK", "MUC", "LHR", "SFO", "SJC"]
#
#
# Example 2:
#
# Input: [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
# Output: ["JFK","ATL","JFK","SFO","ATL","SFO"]
# Explanation: Another possible reconstruction is
# ["JFK","SFO","ATL","JFK","ATL","SFO"].
# But it is larger in lexical order.# Time: O(t! / (n1! * n2! * ... nk!)), t is the total number
# ni is the number of the ticket which from is city i,
# k is the total number of cities.
# Space: O(t)
import collections
class Solution(object):
def findItinerary(self, tickets):
"""
:type tickets: List[List[str]]
:rtype: List[str]
"""
def route_helper(origin, ticket_cnt, graph, ans):
if ticket_cnt == 0:
return True
graph = collections.defaultdict(list)
for ticket in tickets:
graph[ticket[0]].append([ticket[1], True])
572
for k in graph.keys():
graph[k].sort()
origin = "JFK"
ans = [origin]
route_helper(origin, len(tickets), graph, ans)
return ans
573
add-two-numbers.py
# You are given two non-empty linked lists representing two non-negative
# integers. The digits are stored in reverse order and each of their nodes contain
# a single digit. Add the two numbers and return it as a linked list.
#
# You may assume the two numbers do not contain any leading zero, except the
# number 0 itself.
#
# Example:
#
# Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
# Output: 7 -> 0 -> 8
# Explanation: 342 + 465 = 807.# Time: O(n)
# Space: O(1)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
dummy = ListNode(0)
current, carry = dummy, 0
while l1 or l2:
val = carry
if l1:
val += l1.val
l1 = l1.next
if l2:
val += l2.val
l2 = l2.next
carry, val = divmod(val, 10)
current.next = ListNode(val)
current = current.next
if carry == 1:
current.next = ListNode(1)
return dummy.next
574
prison-cells-after-n-days.py
# Example 2:
#
# Input: cells = [1,0,0,1,0,0,1,0], N = 1000000000
# Output: [0,0,1,1,1,1,1,0]
#
#
#
#
# Note:
#
#
# cells.length == 8
# cells[i] is in {0, 1}
# 1 <= N <= 10^9# Time: O(1)
# Space: O(1)
class Solution(object):
def prisonAfterNDays(self, cells, N):
"""
:type cells: List[int]
:type N: int
:rtype: List[int]
"""
N -= max(N-1, 0) // 14 * 14 # 14 is got from Solution2
for i in xrange(N):
cells = [0] + [cells[i-1] ^ cells[i+1] ^ 1 for i in xrange(1, 7)] + [0]
return cells
# Time: O(1)
# Space: O(1)
class Solution2(object):
def prisonAfterNDays(self, cells, N):
"""
:type cells: List[int]
:type N: int
:rtype: List[int]
"""
cells = tuple(cells)
lookup = {}
while N:
lookup[cells] = N
N -= 1
cells = tuple([0] + [cells[i - 1] ^ cells[i + 1] ^ 1 for i in xrange(1, 7)] + [0])
if cells in lookup:
assert(lookup[cells] - N in (1, 7, 14))
N %= lookup[cells] - N
break
while N:
N -= 1
cells = tuple([0] + [cells[i - 1] ^ cells[i + 1] ^ 1 for i in xrange(1, 7)] + [0])
return list(cells)
575
path-with-maximum-gold.py
# In a gold mine grid of size m * n, each cell in this mine has an integer
# representing the amount of gold in that cell, 0 if it is empty.
#
# Return the maximum amount of gold you can collect under the conditions:
#
#
# Every time you are located in a cell you will collect all the gold in
# that cell.
# From your position you can walk one step to the left, right, up or down.
# You can't visit the same cell more than once.
# Never visit a cell with 0 gold.
# You can start and stop collecting gold from any position in the grid
# that has some gold.
#
#
#
# Example 1:
#
# Input: grid = [[0,6,0],[5,8,7],[0,9,0]]
# Output: 24
# Explanation:
# [[0,6,0],
# [5,8,7],
# [0,9,0]]
# Path to get the maximum gold, 9 -> 8 -> 7.
#
#
# Example 2:
#
# Input: grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]]
# Output: 28
# Explanation:
# [[1,0,7],
# [2,0,6],
# [3,4,5],
# [0,3,0],
# [9,0,20]]
# Path to get the maximum gold, 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7.
#
#
#
# Constraints:
#
#
# 1 <= grid.length, grid[i].length <= 15
# 0 <= grid[i][j] <= 100
# There are at most 25 cells containing gold.# Time: O(m^2 * n^2)
# Space: O(m * n)
class Solution(object):
def getMaximumGold(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
def backtracking(grid, i, j):
result = 0
576
grid[i][j] *= -1
for dx, dy in directions:
ni, nj = i+dx, j+dy
if not (0 <= ni < len(grid) and
0 <= nj < len(grid[0]) and
grid[ni][nj] > 0):
continue
result = max(result, backtracking(grid, ni, nj))
grid[i][j] *= -1
return grid[i][j] + result
result = 0
for i in xrange(len(grid)):
for j in xrange(len(grid[0])):
if grid[i][j]:
result = max(result, backtracking(grid, i, j))
return result
577
unique-binary-search-trees.py
# Given n, how many structurally unique BST's (binary search trees) that store
# values 1 ... n?
#
# Example:
#
# Input: 3
# Output: 5
# Explanation:
# Given n = 3, there are a total of 5 unique BST's:
#
# 1 3 3 2 1
# \ / / / \ \
# 3 2 1 1 3 2
# / / \ \
# 2 1 2 3
#
#
#
# Constraints:
#
#
# 1 <= n <= 19# Time: O(n)
# Space: O(1)
class Solution(object):
def numTrees(self, n):
"""
:type n: int
:rtype: int
"""
if n == 0:
return 1
# Time: O(n^2)
# Space: O(n)
# DP solution.
class Solution2(object):
# @return an integer
def numTrees(self, n):
counts = [1, 1]
for i in xrange(2, n + 1):
count = 0
for j in xrange(i):
count += counts[j] * counts[i - j - 1]
counts.append(count)
return counts[-1]
578
minimum-domino-rotations-for-equal-row.py
# In a row of dominoes, A[i] and B[i] represent the top and bottom halves of the
# i-th domino. (A domino is a tile with two numbers from 1 to 6 - one on each
# half of the tile.)
#
# We may rotate the i-th domino, so that A[i] and B[i] swap values.
#
# Return the minimum number of rotations so that all the values in A are the
# same, or all the values in B are the same.
#
# If it cannot be done, return -1.
#
#
#
# Example 1:
#
#
#
# Input: A = [2,1,2,4,2,2], B = [5,2,6,2,3,2]
# Output: 2
# Explanation:
# The first figure represents the dominoes as given by A and B: before we do any
# rotations.
# 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.
#
#
# Example 2:
#
# Input: A = [3,5,1,2,3], B = [3,6,3,3,4]
# Output: -1
# Explanation:
# In this case, it is not possible to rotate the dominoes to make one row of
# values equal.
#
#
#
#
# Note:
#
#
# 1 <= A[i], B[i] <= 6
# 2 <= A.length == B.length <= 20000# Time: O(n)
# Space: O(1)
import itertools
class Solution(object):
def minDominoRotations(self, A, B):
"""
:type A: List[int]
:type B: List[int]
:rtype: int
"""
intersect = reduce(set.__and__, [set(d) for d in itertools.izip(A, B)])
if not intersect:
return -1
x = intersect.pop()
579
return min(len(A)-A.count(x), len(B)-B.count(x))
580
reveal-cards-in-increasing-order.py
# In a deck of cards, every card has a unique integer. You can order the deck
# in any order you want.
#
# Initially, all the cards start face down (unrevealed) in one deck.
#
# Now, you do the following steps repeatedly, until all cards are revealed:
#
#
# Take the top card of the deck, reveal it, and take it out of the deck.
# If there are still cards in the deck, put the next top card of the deck
# at the bottom of the deck.
# If there are still unrevealed cards, go back to step 1. Otherwise,
# stop.
#
#
# Return an ordering of the deck that would reveal the cards in increasing
# order.
#
# The first entry in the answer is considered to be the top of the deck.
#
#
#
#
# Example 1:
#
# Input: [17,13,11,2,3,5,7]
# Output: [2,13,3,11,5,17,7]
# Explanation:
# We get the deck in the order [17,13,11,2,3,5,7] (this order doesn't matter),
# and reorder it.
# After reordering, the deck starts as [2,13,3,11,5,17,7], where 2 is the top of
# the deck.
# We reveal 2, and move 13 to the bottom. The deck is now [3,11,5,17,7,13].
# We reveal 3, and move 11 to the bottom. The deck is now [5,17,7,13,11].
# We reveal 5, and move 17 to the bottom. The deck is now [7,13,11,17].
# We reveal 7, and move 13 to the bottom. The deck is now [11,17,13].
# We reveal 11, and move 17 to the bottom. The deck is now [13,17].
# We reveal 13, and move 17 to the bottom. The deck is now [17].
# We reveal 17.
# Since all the cards revealed are in increasing order, the answer is correct.
#
#
#
#
#
# Note:
#
#
# 1 <= A.length <= 1000
# 1 <= A[i] <= 10^6
# A[i] != A[j] for all i != j# Time: O(n)
# Space: O(n)
import collections
class Solution(object):
def deckRevealedIncreasing(self, deck):
581
"""
:type deck: List[int]
:rtype: List[int]
"""
d = collections.deque()
deck.sort(reverse=True)
for i in deck:
if d:
d.appendleft(d.pop())
d.appendleft(i)
return list(d)
582
fruit-into-baskets.py
# In a row of trees, the i-th tree produces fruit with type tree[i].
#
# You start at any tree of your choice, then repeatedly perform the following
# steps:
#
#
# Add one piece of fruit from this tree to your baskets. If you cannot,
# stop.
# Move to the next tree to the right of the current tree. If there is no
# tree to the right, stop.
#
#
# Note that you do not have any choice after the initial choice of starting
# tree: you must perform step 1, then step 2, then back to step 1, then step 2,
# and so on until you stop.
#
# You have two baskets, and each basket can carry any quantity of fruit, but you
# want each basket to only carry one type of fruit each.
#
# What is the total amount of fruit you can collect with this procedure?
#
#
#
# Example 1:
#
# Input: [1,2,1]
# Output: 3
# Explanation: We can collect [1,2,1].
#
#
#
# Example 2:
#
# Input: [0,1,2,2]
# Output: 3
# Explanation: We can collect [1,2,2].
# If we started at the first tree, we would only collect [0, 1].
#
#
#
# Example 3:
#
# Input: [1,2,3,2,2]
# Output: 4
# Explanation: We can collect [2,3,2,2].
# If we started at the first tree, we would only collect [1, 2].
#
#
#
# Example 4:
#
# Input: [3,3,3,1,2,1,1,2,3,3,4]
# Output: 5
# Explanation: We can collect [1,2,1,1,2].
# If we started at the first tree or the eighth tree, we would only collect 4
# fruits.
#
#
583
#
#
#
#
#
# Note:
#
#
# 1 <= tree.length <= 40000
# 0 <= tree[i] < tree.length# Time: O(n)
# Space: O(1)
import collections
class Solution(object):
def totalFruit(self, tree):
"""
:type tree: List[int]
:rtype: int
"""
count = collections.defaultdict(int)
result, i = 0, 0
for j, v in enumerate(tree):
count[v] += 1
while len(count) > 2:
count[tree[i]] -= 1
if count[tree[i]] == 0:
del count[tree[i]]
i += 1
result = max(result, j-i+1)
return result
584
binary-tree-preorder-traversal.py
# Given a binary tree, return the preorder traversal of its nodes' values.
#
# Example:
#
# Input: [1,null,2,3]
# 1
# \
# 2
# /
# 3
#
# Output: [1,2,3]
#
#
# Follow up: Recursive solution is trivial, could you do it iteratively?# Time: O(n)
# Space: O(1)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
if node.right is None:
result.append(curr.val)
node.right = curr
curr = curr.left
else:
node.right = None
curr = curr.right
return result
# Time: O(n)
# Space: O(h)
# Stack Solution
class Solution2(object):
def preorderTraversal(self, root):
"""
585
:type root: TreeNode
:rtype: List[int]
"""
result, stack = [], [(root, False)]
while stack:
root, is_visited = stack.pop()
if root is None:
continue
if is_visited:
result.append(root.val)
else:
stack.append((root.right, False))
stack.append((root.left, False))
stack.append((root, True))
return result
586
reverse-words-in-a-string.py
# Given an input string, reverse the string word by word.
#
#
#
# Example 1:
#
# Input: "the sky is blue"
# Output: "blue is sky the"
#
#
# Example 2:
#
# Input: " hello world! "
# Output: "world! hello"
# Explanation: Your reversed string should not contain leading or trailing
# spaces.
#
#
# Example 3:
#
# Input: "a good example"
# Output: "example good a"
# Explanation: You need to reduce multiple spaces between two words to a single
# space in the reversed string.
#
#
#
#
# Note:
#
#
# A word is defined as a sequence of non-space characters.
# Input string may contain leading or trailing spaces. However, your
# reversed string should not contain leading or trailing spaces.
# You need to reduce multiple spaces between two words to a single space
# in the reversed string.
#
#
#
#
# Follow up:
#
# For C programmers, try to solve it in-place in O(1) extra space.# Time: O(n)
# Space: O(n)
class Solution(object):
# @param s, a string
# @return a string
def reverseWords(self, s):
return ' '.join(reversed(s.split()))
587
swap-nodes-in-pairs.py
# Given a linked list, swap every two adjacent nodes and return its head.
#
# You may not modify the values in the list's nodes, only nodes itself may be
# changed.
#
#
#
# Example:
#
# Given 1->2->3->4, you should return the list as 2->1->4->3.# Time: O(n)
# Space: O(1)
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
def __repr__(self):
if self:
return "{} -> {}".format(self.val, self.next)
class Solution(object):
# @param a ListNode
# @return a ListNode
def swapPairs(self, head):
dummy = ListNode(0)
dummy.next = head
current = dummy
while current.next and current.next.next:
next_one, next_two, next_three = current.next, current.next.next, current.next.next.next
current.next = next_two
next_two.next = next_one
next_one.next = next_three
current = next_one
return dummy.next
588
convert-sorted-list-to-binary-search-tree.py
# Given the head of a singly linked list where elements are sorted in ascending
# order, convert it to a height balanced BST.
#
# For this problem, a height-balanced binary tree is defined as a binary tree in
# which the depth of the two subtrees of every node never differ by more than 1.
#
#
# Example 1:
#
# Input: head = [-10,-3,0,5,9]
# Output: [0,-3,9,-10,null,5]
# Explanation: One possible answer is [0,-3,9,-10,null,5], which represents the
# shown height balanced BST.
#
#
# Example 2:
#
# Input: head = []
# Output: []
#
#
# Example 3:
#
# Input: head = [0]
# Output: [0]
#
#
# Example 4:
#
# Input: head = [1,3]
# Output: [3,1]
#
#
#
# Constraints:
#
#
# The numner of nodes in head is in the range [0, 2 * 10^4].
# -10^5 <= Node.val <= 10^5# Time: O(n)
# Space: O(logn)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
#
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
head = None
# @param head, a list node
# @return a tree node
def sortedListToBST(self, head):
589
current, length = head, 0
while current is not None:
current, length = current.next, length + 1
self.head = head
return self.sortedListToBSTRecu(0, length)
590
shortest-path-in-binary-matrix.py
# Example 2:
#
# Input: [[0,0,0],[1,1,0],[1,1,0]]
#
#
# Output: 4# Time: O(n^2)
# Space: O(n)
import collections
class Solution(object):
def shortestPathBinaryMatrix(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
directions = [(-1, -1), (-1, 0), (-1, 1), \
( 0, -1), ( 0, 1), \
( 1, -1), ( 1, 0), ( 1, 1)]
result = 0
q = collections.deque([(0, 0)])
while q:
result += 1
next_depth = collections.deque()
while q:
i, j = q.popleft()
if 0 <= i < len(grid) and \
0 <= j < len(grid[0]) and \
not grid[i][j]:
grid[i][j] = 1
if i == len(grid)-1 and j == len(grid)-1:
return result
for d in directions:
next_depth.append((i+d[0], j+d[1]))
q = next_depth
return -1
591
number-of-enclaves.py
# Given a 2D array A, each cell is 0 (representing sea) or 1 (representing land)
#
# A move consists of walking from one land square 4-directionally to another
# land square, or off the boundary of the grid.
#
# Return the number of land squares in the grid for which we cannot walk off the
# boundary of the grid in any number of moves.
#
#
#
# Example 1:
#
# Input: [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
# Output: 3
# Explanation:
# There are three 1s that are enclosed by 0s, and one 1 that isn't enclosed
# because its on the boundary.
#
# Example 2:
#
# Input: [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
# Output: 0
# Explanation:
# All 1s are either on the boundary or can reach the boundary.
#
#
#
#
# Note:
#
#
# 1 <= A.length <= 500
# 1 <= A[i].length <= 500
# 0 <= A[i][j] <= 1
# All rows have the same size.# Time: O(m * n)
# Space: O(m * n)
class Solution(object):
def numEnclaves(self, A):
"""
:type A: List[List[int]]
:rtype: int
"""
directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]
def dfs(A, i, j):
if not (0 <= i < len(A) and 0 <= j < len(A[0]) and A[i][j]):
return
A[i][j] = 0
for d in directions:
dfs(A, i+d[0], j+d[1])
for i in xrange(len(A)):
dfs(A, i, 0)
dfs(A, i, len(A[0])-1)
for j in xrange(1, len(A[0])-1):
dfs(A, 0, j)
dfs(A, len(A)-1, j)
return sum(sum(row) for row in A)
592
593
word-search.py
# Given a 2D board and a word, find if the word exists in the grid.
#
# The word can be constructed from letters of sequentially adjacent cell, where
# "adjacent" cells are those horizontally or vertically neighboring. The same
# letter cell may not be used more than once.
#
# Example:
#
# board =
# [
# ['A','B','C','E'],
# ['S','F','C','S'],
# ['A','D','E','E']
# ]
#
# Given word = "ABCCED", return true.
# Given word = "SEE", return true.
# Given word = "ABCB", return false.
#
#
#
# Constraints:
#
#
# board and word consists only of lowercase and uppercase English letters.
# 1 <= board.length <= 200
# 1 <= board[i].length <= 200
# 1 <= word.length <= 10^3# Time: O(m * n * l)
# Space: O(l)
class Solution(object):
# @param board, a list of lists of 1 length string
# @param word, a string
# @return a boolean
def exist(self, board, word):
visited = [[False for j in xrange(len(board[0]))] for i in xrange(len(board))]
for i in xrange(len(board)):
for j in xrange(len(board[0])):
if self.existRecu(board, word, 0, i, j, visited):
return True
return False
visited[i][j] = True
result = self.existRecu(board, word, cur + 1, i + 1, j, visited) or\
self.existRecu(board, word, cur + 1, i - 1, j, visited) or\
self.existRecu(board, word, cur + 1, i, j + 1, visited) or\
self.existRecu(board, word, cur + 1, i, j - 1, visited)
visited[i][j] = False
594
return result
595
iterator-for-combination.py
# Design an Iterator class, which has:
#
#
# A constructor that takes a string characters of sorted distinct
# lowercase English letters and a number combinationLength as arguments.
# A function next() that returns the next combination of length
# combinationLength in lexicographical order.
# A function hasNext() that returns True if and only if there exists a
# next combination.
#
#
#
#
# Example:
#
# CombinationIterator iterator = new CombinationIterator("abc", 2); // creates
# the iterator.
#
# iterator.next(); // returns "ab"
# iterator.hasNext(); // returns true
# iterator.next(); // returns "ac"
# iterator.hasNext(); // returns true
# iterator.next(); // returns "bc"
# iterator.hasNext(); // returns false
#
#
#
# Constraints:
#
#
# 1 <= combinationLength <= characters.length <= 15
# There will be at most 10^4 function calls per test.
# It's guaranteed that all calls of the function next are valid.# Time: O(k), per operation
# Space: O(k)
import itertools
class CombinationIterator(object):
def next(self):
"""
:rtype: str
"""
self.__curr = "".join(self.__it.next())
return self.__curr
def hasNext(self):
"""
596
:rtype: bool
"""
return self.__curr != self.__last
class CombinationIterator2(object):
def __iterative_backtracking(self):
def conquer():
if len(curr) == self.__combinationLength:
return curr
def prev_divide(c):
curr.append(c)
def divide(i):
if len(curr) != self.__combinationLength:
for j in reversed(xrange(i, len(self.__characters)-(self.__combinationLength-len(curr)-1))):
stk.append(functools.partial(post_divide))
stk.append(functools.partial(divide, j+1))
stk.append(functools.partial(prev_divide, self.__characters[j]))
stk.append(functools.partial(conquer))
def post_divide():
curr.pop()
curr = []
stk = [functools.partial(divide, 0)]
while stk:
result = stk.pop()()
if result is not None:
yield result
def next(self):
"""
:rtype: str
"""
self.__curr = "".join(next(self.__it))
return self.__curr
def hasNext(self):
"""
:rtype: bool
"""
597
return self.__curr != self.__last
598
complete-binary-tree-inserter.py
# Example 1:
#
# Input: inputs = ["CBTInserter","insert","get_root"], inputs = [[[1]],[2],[]]
# Output: [null,1,[1,2]]
#
#
#
# Example 2:
#
# Input: inputs = ["CBTInserter","insert","insert","get_root"], inputs =
# [[[1,2,3,4,5,6]],[7],[8],[]]
# Output: [null,3,4,[1,2,3,4,5,6,7,8]]
#
#
#
#
#
# Note:
#
#
# The initial given tree is complete and contains between 1 and 1000
# nodes.
# CBTInserter.insert is called at most 10000 times per test case.
# Every value of a given or inserted node is between 0 and 5000.# Time: ctor: O(n)
# insert: O(1)
# get_root: O(1)
# Space: O(n)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class CBTInserter(object):
599
return self.__tree[(n-1)//2].val
def get_root(self):
"""
:rtype: TreeNode
"""
return self.__tree[0]
600
print-foobar-alternately.py
# Suppose you are given the following code:
#
# class FooBar {
# public void foo() {
# for (int i = 0; i < n; i++) {
# print("foo");
# }
# }
#
# public void bar() {
# for (int i = 0; i < n; i++) {
# print("bar");
# }
# }
# }
#
#
# The same instance of FooBar will be passed to two different threads. Thread A
# will call foo() while thread B will call bar(). Modify the given program to
# output "foobar" n times.
#
#
#
# Example 1:
#
# Input: n = 1
# Output: "foobar"
# Explanation: There are two threads being fired asynchronously. One of them
# calls foo(), while the other calls bar(). "foobar" is being output 1 time.
#
#
# Example 2:
#
# Input: n = 2
# Output: "foobarfoobar"
# Explanation: "foobar" is being output 2 times.# Time: O(n)
# Space: O(1)
import threading
class FooBar(object):
def __init__(self, n):
self.__n = n
self.__curr = False
self.__cv = threading.Condition()
601
printFoo()
self.__cv.notify()
602
minimum-remove-to-make-valid-parentheses.py
# Given a string s of '(' , ')' and lowercase English characters.
#
# Your task is to remove the minimum number of parentheses ( '(' or ')', in any
# positions ) so that the resulting parentheses string is valid and return any
# valid string.
#
# Formally, a parentheses string is valid if and only if:
#
#
# It is the empty string, contains only lowercase characters, or
# It can be written as AB (A concatenated with B), where A and B are valid
# strings, or
# It can be written as (A), where A is a valid string.
#
#
#
# Example 1:
#
# Input: s = "lee(t(c)o)de)"
# Output: "lee(t(c)o)de"
# Explanation: "lee(t(co)de)" , "lee(t(c)ode)" would also be accepted.
#
#
# Example 2:
#
# Input: s = "a)b(c)d"
# Output: "ab(c)d"
#
#
# Example 3:
#
# Input: s = "))(("
# Output: ""
# Explanation: An empty string is also valid.
#
#
# Example 4:
#
# Input: s = "(a(b(c)d)"
# Output: "a(b(c)d)"
#
#
#
# Constraints:
#
#
# 1 <= s.length <= 10^5
# s[i] is one of '(' , ')' and lowercase English letters.# Time: O(n)
# Space: O(n)
class Solution(object):
def minRemoveToMakeValid(self, s):
"""
:type s: str
:rtype: str
"""
result = list(s)
count = 0
603
for i, v in enumerate(result):
if v == '(':
count += 1
elif v == ')':
if count:
count -= 1
else:
result[i] = ""
if count:
for i in reversed(xrange(len(result))):
if result[i] == '(':
result[i] = ""
count -= 1
if not count:
break
return "".join(result)
604
stone-game.py
# Alex and Lee play a game with piles of stones. There are an even number
# of piles arranged in a row, and each pile has a positive integer number of
# stones piles[i].
#
# The objective of the game is to end with the most stones. The total number of
# stones is odd, so there are no ties.
#
# Alex and Lee take turns, with Alex starting first. Each turn, a player takes
# the entire pile of stones from either the beginning or the end of the row. This
# continues until there are no more piles left, at which point the person with the
# most stones wins.
#
# Assuming Alex and Lee play optimally, return True if and only if Alex wins the
# game.
#
#
# Example 1:
#
# Input: piles = [5,3,4,5]
# Output: true
# Explanation:
# Alex starts first, and can only take the first 5 or the last 5.
# Say he takes the first 5, so that the row becomes [3, 4, 5].
# If Lee takes 3, then the board is [4, 5], and Alex takes 5 to win with 10
# points.
# If Lee takes the last 5, then the board is [3, 4], and Alex takes 4 to win
# with 9 points.
# This demonstrated that taking the first 5 was a winning move for Alex, so we
# return true.
#
#
#
# Constraints:
#
#
# 2 <= piles.length <= 500
# piles.length is even.
# 1 <= piles[i] <= 500
# sum(piles) is odd.# Time: O(n^2)
# Space: O(n)
class Solution(object):
def stoneGame(self, piles):
"""
:type piles: List[int]
:rtype: bool
"""
if len(piles) % 2 == 0 or len(piles) == 1:
return True
dp = [0] * len(piles)
for i in reversed(xrange(len(piles))):
dp[i] = piles[i]
for j in xrange(i+1, len(piles)):
dp[j] = max(piles[i] - dp[j], piles[j] - dp[j - 1])
return dp[-1] >= 0
605
longest-substring-without-repeating-characters.py
# Example 1:
#
# Input: "abcabcbb"
# Output: 3
# Explanation: The answer is "abc", with the length of 3.
#
#
#
# Example 2:
#
# Input: "bbbbb"
# Output: 1
# Explanation: The answer is "b", with the length of 1.
#
#
#
# Example 3:
#
# Input: "pwwkew"
# Output: 3
# Explanation: The answer is "wke", with the length of 3.
# Note that the answer must be a substring, "pwke" is a subsequence
# and not a substring.# Time: O(n)
# Space: O(1)
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
result, left = 0, 0
lookup = {}
for right in xrange(len(s)):
if s[right] in lookup:
left = max(left, lookup[s[right]]+1)
lookup[s[right]] = right
result = max(result, right-left+1)
return result
606
combination-sum-ii.py
# Given a collection of candidate numbers (candidates) and a target number
# (target), find all unique combinations in candidates where the candidate numbers
# sums to target.
#
# Each number in candidates may only be used once in the combination.
#
# Note:
#
#
# All numbers (including target) will be positive integers.
# The solution set must not contain duplicate combinations.
#
#
# Example 1:
#
# Input: candidates = [10,1,2,7,6,1,5], target = 8,
# A solution set is:
# [
# [1, 7],
# [1, 2, 5],
# [2, 6],
# [1, 1, 6]
# ]
#
#
# Example 2:
#
# Input: candidates = [2,5,2,1,2], target = 5,
# A solution set is:
# [
# [1,2,2],
# [5]
# ]# Time: O(k * C(n, k))
# Space: O(k)
class Solution(object):
# @param candidates, a list of integers
# @param target, integer
# @return a list of lists of integers
def combinationSum2(self, candidates, target):
result = []
self.combinationSumRecu(sorted(candidates), result, 0, [], target)
return result
607
task-scheduler.py
# Given a characters array tasks, representing the tasks a CPU needs to do,
# where each letter represents a different task. Tasks could be done in any order.
# Each task is done in one unit of time. For each unit of time, the CPU could
# complete either one task or just be idle.
#
# However, there is a non-negative integer n that represents the cooldown period
# between two same tasks (the same letter in the array), that is that there must
# be at least n units of time between any two same tasks.
#
# Return the least number of units of times that the CPU will take to finish all
# the given tasks.
#
#
# Example 1:
#
# Input: tasks = ["A","A","A","B","B","B"], n = 2
# Output: 8
# Explanation:
# A -> B -> idle -> A -> B -> idle -> A -> B
# There is at least 2 units of time between any two same tasks.
#
#
# Example 2:
#
# Input: tasks = ["A","A","A","B","B","B"], n = 0
# Output: 6
# Explanation: On this case any permutation of size 6 would work since n = 0.
# ["A","A","A","B","B","B"]
# ["A","B","A","B","A","B"]
# ["B","B","B","A","A","A"]
# ...
# And so on.
#
#
# Example 3:
#
# Input: tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2
# Output: 16
# Explanation:
# One possible solution is
# A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> idle -> idle -> A -> idle ->
# idle -> A
#
#
#
# Constraints:
#
#
# 1 <= task.length <= 104
# tasks[i] is upper-case English letter.
# The integer n is in the range [0, 100].# Time: O(n)
# Space: O(26) = O(1)
class Solution(object):
def leastInterval(self, tasks, n):
608
"""
:type tasks: List[str]
:type n: int
:rtype: int
"""
counter = Counter(tasks)
_, max_count = counter.most_common(1)[0]
609
find-minimum-in-rotated-sorted-array.py
# Suppose an array sorted in ascending order is rotated at some pivot unknown to
# you beforehand.
#
# (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
#
# Find the minimum element.
#
# You may assume no duplicate exists in the array.
#
# Example 1:
#
# Input: [3,4,5,1,2]
# Output: 1
#
#
# Example 2:
#
# Input: [4,5,6,7,0,1,2]
# Output: 0# Time: O(logn)
# Space: O(1)
class Solution(object):
def findMin(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left, right = 0, len(nums)
target = nums[-1]
return nums[left]
class Solution2(object):
def findMin(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left, right = 0, len(nums) - 1
while left < right and nums[left] >= nums[right]:
mid = left + (right - left) / 2
return nums[left]
610
maximum-width-of-binary-tree.py
# Given a binary tree, write a function to get the maximum width of the given
# tree. The maximum width of a tree is the maximum width among all levels.
#
# The width of one level is defined as the length between the end-nodes (the
# leftmost and right most non-null nodes in the level, where the null nodes
# between the end-nodes are also counted into the length calculation.
#
# It is guaranteed that the answer will in the range of 32-bit signed integer.
#
# Example 1:
#
# Input:
#
# 1
# / \
# 3 2
# / \ \
# 5 3 9
#
# Output: 4
# Explanation: The maximum width existing in the third level with the length 4
# (5,3,null,9).
#
#
# Example 2:
#
# Input:
#
# 1
# /
# 3
# / \
# 5 3
#
# Output: 2
# Explanation: The maximum width existing in the third level with the length 2
# (5,3).
#
#
# Example 3:
#
# Input:
#
# 1
# / \
# 3 2
# /
# 5
#
# Output: 2
# Explanation: The maximum width existing in the second level with the length 2
# (3,2).
#
#
# Example 4:
#
# Input:
#
611
# 1
# / \
# 3 2
# / \
# 5 9
# / \
# 6 7
# Output: 8
# Explanation:The maximum width existing in the fourth level with the length 8
# (6,null,null,null,null,null,null,7).
#
#
#
# Constraints:
#
#
# The given binary tree will have between 1 and 3000 nodes.# Time: O(n)
# Space: O(h)
class Solution(object):
def widthOfBinaryTree(self, root):
"""
:type root: TreeNode
:rtype: int
"""
def dfs(node, i, depth, leftmosts):
if not node:
return 0
if depth >= len(leftmosts):
leftmosts.append(i)
return max(i-leftmosts[depth]+1, \
dfs(node.left, i*2, depth+1, leftmosts), \
dfs(node.right, i*2+1, depth+1, leftmosts))
leftmosts = []
return dfs(root, 1, 0, leftmosts)
612
fraction-addition-and-subtraction.py
# Given a string representing an expression of fraction addition and
# subtraction, you need to return the calculation result in string format. The
# final result should be irreducible fraction. If your final result is an integer,
# say 2, you need to change it to the format of fraction that has denominator 1.
# So in this case, 2 should be converted to 2/1.
#
# Example 1:
#
# Input:"-1/2+1/2"
# Output: "0/1"
#
#
#
# Example 2:
#
# Input:"-1/2+1/2+1/3"
# Output: "1/3"
#
#
#
# Example 3:
#
# Input:"1/3-1/2"
# Output: "-1/6"
#
#
#
# Example 4:
#
# Input:"5/3+1/3"
# Output: "2/1"
#
#
#
# Note:
#
#
# The input string only contains '0' to '9', '/', '+' and '-'. So does the
# output.
# Each fraction (input and output) has format ±numerator/denominator. If the
# first input fraction or the output is positive, then '+' will be omitted.
# The input only contains valid irreducible fractions, where the numerator and
# denominator of each fraction will always be in the range [1,10]. If the
# denominator is 1, it means this fraction is actually an integer in a fraction
# format defined above.
# The number of given fractions will be in the range [1,10].
# The numerator and denominator of the final result are guaranteed to be valid
# and in the range of 32-bit int.# Time: O(nlogx), x is the max denominator
# Space: O(n)
import re
class Solution(object):
def fractionAddition(self, expression):
"""
:type expression: str
:rtype: str
613
"""
def gcd(a, b):
while b:
a, b = b, a%b
return a
614