Leetcode 48: Rotate Image

48. Rotate Image

  • Total Accepted: 84852
  • Total Submissions: 232792
  • Difficulty: Medium
  • Contributors: Admin

You are given an n x n 2D matrix representing an image.

Rotate the image by 90 degrees (clockwise).

Follow up:
Could you do this in-place?

 

 

General Idea:

You need to first flip matrix upside down. Then swap elements mirror to the diagonal.

<span class="hljs-comment"> # clockwise rotate
 # first reverse up to down, then swap the symmetry 
 # 1 2 3     7 8 9     7 4 1
 # 4 5 6  => 4 5 6  => 8 5 2
 # 7 8 9     1 2 3     9 6 3</span>

 

Code

class Solution(object):
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        matrix[:] = zip(*matrix[::-1])
        

 

Idea

Pythonic way. 

 

Code

class Solution(object):
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        
        self.upside_down(matrix)
        self.mirror_diag(matrix)

    def upside_down(self, matrix):
        n = len(matrix)
        for i in xrange(n/2):
            for j in xrange(n):
                matrix[i][j], matrix[n-i-1][j] = matrix[n-i-1][j], matrix[i][j]

    def mirror_diag(self, matrix):
        n = len(matrix)
        for i in xrange(n):
            for j in xrange(i+1, n):
                matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

 

Idea

Self implement upside down and mirror.

 

Reference:

https://discuss.leetcode.com/topic/15295/seven-short-solutions-1-to-7-lines

https://discuss.leetcode.com/topic/6796/a-common-method-to-rotate-the-image/2

Leetcode 13: Roman to Integer

13. Roman to Integer

  • Total Accepted: 111025
  • Total Submissions: 261201
  • Difficulty: Easy
  • Contributors: Admin

Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.

 

Code

class Solution(object):
    def romanToInt(self, s):
        """
        :type s: str
        :rtype: int
        """
        pre = 0
        sum = 0
        mapping = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} 
        for ch in s[::-1]:
            i = mapping[ch]
            if i >= pre:
                sum += i
            else:
                sum -= i
            pre = i

        return sum

 

Idea

Fun to know how to read Roman number!

 

Reference: 

https://discuss.leetcode.com/topic/821/my-solution-for-this-question-but-i-don-t-know-is-there-any-easier-way/2 (Answer from vera_qing)

Leetcode 17: Letter Combinations of a Phone Number

17. Letter Combinations of a Phone Number 

  • Total Accepted: 104864
  • Total Submissions: 335917
  • Difficulty: Medium
  • Contributors: Admin

Given a digit string, 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.

Input:Digit string "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.

 

Code

from collections import deque 
class Solution(object):
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        if digits == "": return []
        
        mapping = ["0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"]
        res = deque([''])
        for i in digits:
            for j in xrange(len(res)):
                s = res.popleft()
                for k in mapping[int(i)]:
                    res.append(s + k)
        
        return list(res)

 

Idea

Use a FIFO queue. Therefore, we can maximally reduce extra space needed.

Reference: https://discuss.leetcode.com/topic/8465/my-java-solution-with-fifo-queue

 

Code

from collections import deque 
class Solution(object):
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        if digits == "": return []
        
        mapping = ["0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"]
        return reduce(lambda acc, d: [x+y for x in acc for y in mapping[int(d)]], digits, [''])

 

Idea 

Pythonic way using reduce.

Reference: https://discuss.leetcode.com/topic/11783/one-line-python-solution

 

 

Leetcode 16: 3Sum Closest

https://leetcode.com/problems/3sum-closest/

16. 3Sum Closest 

  • Total Accepted: 97996
  • Total Submissions: 324135
  • Difficulty: Medium
  • Contributors: Admin

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

    For example, given array S = {-1 2 1 -4}, and target = 1.

    The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

 

Code

import sys

class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums = sorted(nums)
        min_diff = sys.maxint
         
        for i in xrange(len(nums)-2):
            j = i + 1
            k = len(nums)-1
            while j < k:
                cur_sum = nums[i] + nums[j] + nums[k]
                cur_diff = abs(cur_sum - target)
                if cur_diff < min_diff:
                     res = cur_sum
                     min_diff = cur_diff
                if cur_sum > target:
                     k -= 1
                elif cur_sum < target:
                     j += 1
                else:
                     return res

        return res

 

Idea

Sort the array first. Then, create three pointers, ij and k, such that, when i is fixed, j and k are adjusted to make the 3sum approach the target. The total time complexity is O(N^2) where N is the length of nums.

 

 

 

Leetcode 12: Integer to Roman

12. Integer to Roman

  • Total Accepted: 80645
  • Total Submissions: 192971
  • Difficulty: Medium
  • Contributors: Admin

Given an integer, convert it to a roman numeral.

Input is guaranteed to be within the range from 1 to 3999.

 

Code 

class Solution(object):
    def intToRoman(self, num):
        """
        :type num: int
        :rtype: str
        """
        M = ["", "M", "MM", "MMM"]
        C = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"]
        X = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"]
        I = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
        return M[num/1000] + C[(num%1000)/100] + X[(num%100)/10] + I[num%10]

 

Idea

Nothing much.

Leetcode 11: Container With Most Water

11. Container With Most Water 

  • Total Accepted: 99353
  • Total Submissions: 277586
  • Difficulty: Medium
  • Contributors: Admin

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.

 

Code

class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        lp, rp = 0, len(height)-1
        max_area = 0
        while lp < rp:
            max_area = max(max_area, min(height[lp],height[rp]) * (rp-lp))
            if height[lp] < height[rp]:
                lp += 1
            else:
                rp -= 1
        return max_area

 

Idea

The time complexity is O(N). The idea is that if height[lp] < height[rp], then the bottleneck to determine the container volume is height[lp]. That means the container formed by height[lp] and height[rp'] for any rp' < rp must have smaller volume than that formed by height[lp] and height[rp]. In this case, lp should move to right.

You can easily deduct the other case: height[rp] < height[lp].

Reference: https://discuss.leetcode.com/topic/3462/yet-another-way-to-see-what-happens-in-the-o-n-algorithm

 

Leetcode 125: Valid Palindrome

125. Valid Palindrome 

  • Total Accepted: 124387
  • Total Submissions: 499823
  • Difficulty: Easy
  • Contributors: Admin

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.

Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.

For the purpose of this problem, we define empty string as valid palindrome.

 

Code

class Solution(object):
    def isPalindrome(self, s):
        """
        :type s: str
        :rtype: bool
        """
        lp, rp = 0, len(s)-1
        while lp < rp:
            while lp < rp and not s[lp].isalnum():
                lp += 1
            while lp < rp and not s[rp].isalnum():
                rp -= 1
            if s[lp].lower() != s[rp].lower():
                return False
            lp += 1
            rp -= 1
        
        return True

 

Idea

Not much to say. First time to use string.isalnum().

Leetcode 131: Palindrome Partitioning

131. Palindrome Partitioning

  • Total Accepted: 77657
  • Total Submissions: 260955
  • Difficulty: Medium
  • Contributors: Admin

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

For example, given s = "aab",
Return

[
  ["aa","b"],
  ["a","a","b"]
]

 

Code

 

class Solution(object):
    def partition(self, s):
        """
        :type s: str
        :rtype: List[List[str]]
        """
        res = []
        self.recur(0, s, [], res)
        return res

    def recur(self, cur_idx, s, splits, res):
        if cur_idx == len(s):
            res.append(list(splits))
            return

        for i in xrange(cur_idx + 1, len(s)+1):
            if self.isPalindrome(s[cur_idx:i]):
                splits.append(s[cur_idx:i])
                self.recur(i, s, splits, res)
                splits.pop()

    def isPalindrome(self, ss):
        return ss == ss[::-1]

 

Idea

You progressively try every split position in the string. Check whether substring between the last split position to current split position is palindrome. If so, recursively try the rest of split positions, with the current substring being added to splits.

Reference: https://discuss.leetcode.com/topic/10955/clean-c-backtracking-solution 

 

Leetcode 118: Pascal’s Triangle

https://leetcode.com/problems/pascals-triangle/

118. Pascal’s Triangle 

  • Total Accepted: 103611
  • Total Submissions: 290013
  • Difficulty: Easy
  • Contributors: Admin

Given numRows, generate the first numRows of Pascal’s triangle.

For example, given numRows = 5,
Return

[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]

 

Code

class Solution(object):
    def generate(self, numRows):
        """
        :type numRows: int
        :rtype: List[List[int]]
        """
        if numRows == 0:
            return []
        
        res = [[1]]
        for i in xrange(2, numRows+1):
            new_row = [0] * i
            for j in xrange(i):
                if j == 0:
                    new_row[j] = 1
                elif j == i-1:
                    new_row[j] = 1
                else: 
                    new_row[j] = res[-1][j-1] + res[-1][j]
            res.append(new_row)
            
        return res   

 

Idea

Each element is the sum of adjacent elements in the above line. That’s how Pascal’s Triangle is defined: https://en.wikipedia.org/wiki/Pascal%27s_triangle

 

 

Leetcode 120: Triangle

120. Triangle 

  • Total Accepted: 84503
  • Total Submissions: 265352
  • Difficulty: Medium
  • Contributors: Admin

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.

 

 

Code 

class Solution(object):
    def minimumTotal(self, triangle):
        """
        :type triangle: List[List[int]]
        :rtype: int
        """
        if len(triangle) == 0:
            return 0
        
        if len(triangle) == 1:
            return triangle[0][0] 
        
        last_level_sum = {0:triangle[0][0]}
        for i in xrange(1, len(triangle)):
            this_level_sum = {}
            for j in xrange(len(triangle[i])):    
                if j == 0:
                     this_level_sum[j] = last_level_sum[0] + triangle[i][j]
                elif j == len(triangle[i])-1:
                     this_level_sum[j] = last_level_sum[j-1] + triangle[i][j]
                else:
                     this_level_sum[j] = min(last_level_sum[j], last_level_sum[j-1]) + triangle[i][j]
        
            last_level_sum = this_level_sum         

        return min(last_level_sum.values())

 

 

Idea

You go from top to bottom. Record the minimum sum until every layer. If you use a bottom-up DP, the solution can be more elegant.

Reference:

https://discuss.leetcode.com/topic/1669/dp-solution-for-triangle/2