Leetcode!
  • LeetCode!
  • My personal guide to Leetcode
  • Array
    • 11. Container With Most Water
    • 15. 3Sum
    • 219. Contains Duplicate II
    • 238. Product of Array Except Self
    • 245. Shortest Word Distance III
    • 392. Is Subsequence
    • 442. Find All Duplicates in an Array
    • 561. Array Partition I
    • 661. Image Smoother
    • 697. Degree of an Array
    • 723. Candy Crush
    • 832. Flipping an Image
  • Backtracking
    • 294. Flip Game II
    • 401. Binary Watch
    • 1079. Letter Tile Possibilities
  • Binary Search
    • 744. Find Smallest Letter Greater Than Target
    • 852. Peak Index in a Mountain Array
  • String
    • 6. ZigZag Conversion
    • 17. Letter Combinations of a Phone Number
    • 38. Count and Say
    • 521. Longest Uncommon Subsequence I
    • 544. Output Contest Matches
    • 937. Reorder Data in Log Files
  • Design
    • 251. Flatten 2D Vector
    • 281. Zigzag Iterator
  • Hash Table
    • 1. Two Sum
    • 508. Most Frequent Subtree Sum
    • 884. Uncommon Words from Two Sentences
    • 734. Sentence Similarity
  • Linked List
    • 2. Add Two Numbers
  • Unsorted
    • 917. Reverse Only Letters
  • Math
    • 43. Multiply Strings
    • 462. Minimum Moves to Equal Array Elements II
    • 553. Optimal Division
    • 800. Similar RGB Color
  • Greedy
    • 406. Queue Reconstruction by Height
    • 861. Score After Flipping Matrix
  • Tree
    • 701. Insert into a Binary Search Tree
    • 897. Increasing Order Search Tree
  • Divide and Conquer
    • 53. Maximum Subarray
  • Dynamic Programming
    • 62. Unique Paths
    • 63. Unique Paths II
    • 64. Minimum Path Sum
    • 120. Triangle
    • 198. House Robber
    • 213. House Robber II
    • 303. Range Sum Query - Immutable
    • 518. Coin Change 2
    • 750. Number Of Corner Rectangles
    • 337. House Robber III
  • Depth first search
    • 841. Keys and Rooms
  • Trie
    • 677. Map Sum Pairs
  • Two pointer
    • 42. Trapping Rain Water
Powered by GitBook
On this page
  • Approach 1: Brute Force
  • Approach 2: Rotate array to ease gravity
  1. Array

723. Candy Crush

Approach 1: Brute Force

class Solution(object):
    def candyCrush(self, board):
        """
        :type board: List[List[int]]
        :rtype: List[List[int]]
        """
        m, n = len(board), len(board[0])
        def gravity():
            for j in range(n):
                stack = [board[i][j] for i in range(m - 1, -1, -1) if board[i][j] > 0]
                stack += [0] *  (m - len(stack))
                for i in range(m): board[i][j] = stack.pop()
        def crush():
            crush = False
            for i in range(m):
                for j in range(n):
                    if j > 1 and board[i][j] > 0 and board[i][j] == abs(board[i][j - 1]) == abs(board[i][j - 2]):
                        board[i][j - 2:j + 1] = [-abs(board[i][j]) for _ in range(3)]
                        crush = True
                    if i > 1 and board[i][j] != 0 and abs(board[i][j]) == abs(board[i - 1][j]) == abs(board[i - 2][j]):
                        if board[i][j] > 0: board[i][j] *= -1
                        if board[i - 1][j] > 0: board[i - 1][j] *= -1
                        if board[i - 2][j] > 0: board[i - 2][j] *= -1
                        crush = True
            return crush  
        while crush(): gravity()
        return board

Find all the values to be deleted and make them negative and then remove all the negative values from the columns one by one

Time Complexity: O(M*N*C) where C is the number of crushing rounds req

Space Complexity: O(M*N)

Approach 2: Rotate array to ease gravity

class Solution(object):
    def candyCrush(self, board):
        """
        :type board: List[List[int]]
        :rtype: List[List[int]]
        """
        board = map(list,zip(*reversed(board)))
        R, C = len(board), len(board[0])
        while True:
            remove = set()
            for i in range(R):
                for j in range(2, C):
                    if board[i][j] != 0 and board[i][j] == board[i][j-1] == board[i][j-2]:
                        remove |= {(i,j), (i,j-1), (i,j-2)}
            for j in range(C):
                for i in range(2, R):
                    if board[i][j] != 0 and board[i][j] == board[i-1][j] == board[i-2][j]:
                        remove |= {(i,j), (i-1,j), (i-2,j)}
            if remove:
                for i,j in remove: board[i][j] = 0
                for i in range(R):
                    count = 0
                    board[i] = [x for x in board[i] if x]
                    board[i].extend([0]*(C - len(board[i])))
            else:
                break
        return list(reversed(map(list,zip(*board))))

After iterating over all rows and columns each time to find a continuous block of candies to remove, we make them zero. Now instead of having a "gravity" function what made sense was to actually rotate the array counter clockwise and shift each of the items in the row left instead of down in a column.

Time Complexity: O(M*N*C) where C is the number of crushing rounds req

Space Complexity: O(M*N)

Previous697. Degree of an ArrayNext832. Flipping an Image

Last updated 6 years ago