Leetcode 341: Flatten Nested List Iterator

341. Flatten Nested List Iterator

  • Total Accepted: 20339
  • Total Submissions: 55207
  • Difficulty: Medium
  • Contributors: Admin

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:
Given the list [[1,1],2,[1,1]],

By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1].

Example 2:
Given the list [1,[4,[6]]],

By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,4,6].

 

Code

# """
# This is the interface that allows for creating nested lists.
# You should not implement it, or speculate about its implementation
# """
#class NestedInteger(object):
#    def isInteger(self):
#        """
#        @return True if this NestedInteger holds a single integer, rather than a nested list.
#        :rtype bool
#        """
#
#    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 NestedIterator(object):

    def __init__(self, nestedList):
        """
        Initialize your data structure here.
        :type nestedList: List[NestedInteger]
        """
        # initialize a pair. 1st: the next element to explore, 
        # 2nd: the next index of that element to explore, if that element is a list-like NestedInteger
        self.stack = [[nestedList, 0]]
        
    def next(self):
        """
        :rtype: int
        """
        # hasNext() always makes sure the latest element on self.stack
        # is a list containing a non-list NestedInteger
        if self.hasNext():
            l, idx = self.stack.pop()
            return l.getInteger()

    def hasNext(self):
        """
        # hasNext() always makes sure the latest element on self.stack
        # is a list containing a non-list NestedInteger
        
        :rtype: bool
        """
        while self.stack:
            l, idx = self.stack[-1]
            if type(l) is NestedInteger and l.isInteger():
                return True
            else:
                if type(l) is NestedInteger and idx < len(l.getList()): 
                    self.stack[-1][1] += 1
                    self.stack.append([l.getList()[idx], 0])
                # the first added element in self.__init__ is a pure list    
                elif type(l) is list and idx < len(l):
                    self.stack[-1][1] += 1
                    self.stack.append([l[idx], 0])
                else:
                    # pop the element if the idx, the next position to explore, has already
                    # exceeded the length of the element
                    self.stack.pop()
        return False
        

# Your NestedIterator object will be instantiated and called as such:
# i, v = NestedIterator(nestedList), []
# while i.hasNext(): v.append(i.next())

 

Idea

Use a stack to maintain the elements to iterate. The next element to be iterated will be on the top of the stack. The stack is initialized as [nestedList, 0] in self.__init__(), as we are going to explore the first element in nestedList in the future.

In self.next(), we always first call self.hasNext(). The goal of self.hasNext() is to put the next integer on the top of the stack and also a boolean indicating whether there indeed exists the next integer to iterate.

In self.hasNext(), we peek the top element in the stack (line 55). If it is already an integer, return True and we don’t need to arrange the stack further. If it is a list of integers, we need to start exploring that list and put the next integer on the stack. Before that, we need to increase the top element’s index by one (line 60 and 64). This means that the next time when we visit this list, we should start exploring from the updated index.

The advantage of this algorithm is that it does not need to load all integers of the whole list into the stack at one time. Its space complexity is O(K), where K is the depth of the deepest nested list.

Reference: https://discuss.leetcode.com/topic/41870/real-iterator-in-python-java-c

Leetcode 27: Remove Element

27. Remove Element 

  • Total Accepted: 154492
  • Total Submissions: 426032
  • Difficulty: Easy
  • Contributors: Admin

Given an array and a value, remove all instances of that value in place and return the new length.

Do not allocate extra space for another array, you must do this in place with constant memory.

The order of elements can be changed. It doesn’t matter what you leave beyond the new length.

Example:
Given input array nums = [3,2,2,3], val = 3

Your function should return length = 2, with the first two elements of nums being 2.

Hint:

  1. Try two pointers.
  2. Did you use the property of “the order of elements can be changed”?
  3. What happens when the elements to remove are rare?

 

Code

class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        left, right = 0, len(nums)-1
        while left <= right:
            if nums[left] == val:
                nums[left], nums[right] = nums[right], nums[left]
                right -= 1
            else:
                left += 1
            
        return right + 1

 

Idea

Everything on the right of right are elements equal to val.

Leetcode 29: Divide Two Integers

29. Divide Two Integers 

  • Total Accepted: 82624
  • Total Submissions: 519755
  • Difficulty: Medium
  • Contributors: Admin

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

 

 

Code (Naive)

import sys


class Solution(object):
    def divide(self, dividend, divisor):
        """
        :type dividend: int
        :type divisor: int
        :rtype: int
        """
        if not divisor: return sys.maxint
        sign = -1 if (dividend > 0) ^ (divisor > 0) else 1
        dividend, divisor = abs(dividend), abs(divisor)

        res = 0
        while dividend - divisor >= 0:
            dividend -= divisor
            res += 1

        return res * sign

This is  a naive solution, where you count how many times dividend is to divisor by subtracting divisor from dividend until dividend < divisor. This solution causes Time Limit Error when dividend is large and divisor is small.

 

Code

import sys

class Solution(object):
    def divide(self, dividend, divisor):
        """
        :type dividend: int
        :type divisor: int
        :rtype: int
        """
        if not divisor: 
            return sys.maxint
        
        # In python there is no overflow issue.
        # This condition is here for a specific test case.
        if (dividend == -2**31 and divisor == -1):
            return 2**31-1
        
        sign = -1 if (dividend > 0) ^ (divisor > 0) else 1
        dividend, divisor = abs(dividend), abs(divisor)
    
        res = 0
        while dividend >= divisor:
            tmp_divisor = divisor
            tmp_multiple = 1
            while dividend >= (tmp_divisor << 1):
                tmp_divisor <<= 1
                tmp_multiple <<= 1
                
            dividend -= tmp_divisor
            res += tmp_multiple
        
        return res * sign

 

Idea

This is a quicker way to do the division. You approach to the quotient by doubling divisor until dividend < (tmp_divisor << 1). (line 22-27)

Reference: https://discuss.leetcode.com/topic/15568/detailed-explained-8ms-c-solution/2

 

Another idea is to use some mathematical properties to the quotient. If integer size is fixed at 32bit, then the algorithm takes constant time: https://discuss.leetcode.com/topic/17600/32-times-bit-shift-operation-in-c-with-o-1-solution

 

Leetcode 21: Merge Two Sorted Lists

21. Merge Two Sorted Lists

  • Total Accepted: 167826
  • Total Submissions: 448665
  • Difficulty: Easy
  • Contributors: Admin

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

Code

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        headbak = head = ListNode(0)
        while l1 and l2:
            if l1.val < l2.val:
                head.next = l1
                l1 = l1.next
            else:
                head.next = l2
                l2 = l2.next
                
            head = head.next
        
        while l1:
            head.next = l1
            l1 = l1.next
            head = head.next
        
        while l2:
            head.next = l2
            l2 = l2.next
            head = head.next
        
        return headbak.next

Idea

When two lists’ heads are not None, splice the smaller node into the new list and move the list’s head to the next of the smaller pointer. Then, when only one list’s head is not None, concatenate all of its remaining nodes.

See a harder version: Merge k sorted list: https//nb4799.neu.edu/wordpress/?p=926

Leetcode 14: Longest Common Prefix

14. Longest Common Prefix

  • Total Accepted: 131998
  • Total Submissions: 438812
  • Difficulty: Easy
  • Contributors: Admin

Write a function to find the longest common prefix string amongst an array of strings.

 

Code

class Solution(object):
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        if not strs:
            return ""
        
        prefix = ""
        for k in xrange(len(strs[0])):
            for i in xrange(1, len(strs)):
                if k < len(strs[i]) and strs[i][k] == strs[0][k]:
                    continue
                return prefix
            prefix += strs[0][k]
        
        return prefix

 

Idea

Suppose there are N strings and average K length for each string. Then this algorithm takes O(NK) time, which I believe is the fastest solution so far. Note that we start prefix from an empty string. In this way, we only need to test whether to add one character to prefix each time. 

 

Reference: https://discuss.leetcode.com/topic/20991/accepted-c-6-lines-4ms/6

Leetcode 24: Swap Nodes in Pairs

24. Swap Nodes in Pairs 

  • Total Accepted: 130373
  • Total Submissions: 354429
  • Difficulty: Easy
  • Contributors: Admin

Given a linked list, swap every two adjacent nodes and return its head.

For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.

Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.

 

Code

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        # dummy node, the node before head
        node_prev = ListNode(0)
        node_prev.next = head
        node_prev_bak = node_prev
            
        while node_prev.next and node_prev.next.next:
            node1, node2 = node_prev.next, node_prev.next.next
            
            # doing the actual swap
            node_prev.next = node2
            node1.next = node2.next
            node2.next = node1
            
            node_prev = node1
            
        return node_prev_bak.next
        
        

 

 

Idea

Very straightforward. Every time, you do the swapping on the two nodes.

 

Reference

https://discuss.leetcode.com/topic/18860/7-8-lines-c-python-ruby

 

Leetcode 18: 4Sum

18. 4Sum

  • Total Accepted: 92730
  • Total Submissions: 367805
  • Difficulty: Medium
  • Contributors: Admin

Given an array S of n integers, are there elements a, b, c, and d in S 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.

For example, given array S = [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]
]

 

Code

class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        
        if len(nums) < 4: 
            return []

        res = []
        nums = sorted(nums)

        for i in xrange(len(nums)-3):
            if i > 0 and nums[i-1] == nums[i]:
                continue
            for j in xrange(i+1, len(nums)-2):
                if j > i+1 and nums[j-1] == nums[j]:
                    continue
                m, n = j+1, len(nums)-1
                while m < n:
                    if nums[i]+nums[j]+nums[m]+nums[n] == target:
                        res.append((nums[i], nums[j], nums[m], nums[n]))
                        while m < n and nums[m] == nums[m+1]:
                            m += 1
                        while m < n and nums[n] == nums[n-1]:
                            n -=1
                        m += 1
                        n -= 1
                    elif nums[i]+nums[j]+nums[m]+nums[n] < target:
                        m += 1
                    else:
                        n -= 1

        return res
        

 

Idea

As usual, sort the array first. Then create four indices, i, j, m and n. Every time, fix i and j and move m and n as to approach target. Be very careful about dealing with duplicates. (line 16-17, 19-20, 25-28).

Also see 2Sum and 3Sum

 

Reference: https://discuss.leetcode.com/topic/12368/clean-accepted-java-o-n-3-solution-based-on-3sum/2

Leetcode 19: Remove Nth Node From End of List

19. Remove Nth Node From End of List 

  • Total Accepted: 140954
  • Total Submissions: 445848
  • Difficulty: Easy
  • Contributors: Admin

Given a linked list, remove the nth node from the end of list and return its head.

For 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.
Try to do this in one pass.

 

Code

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        i = 0
        head_bak, n_to_last, n_plus_1_to_last = head, head, head
        
        while head:
            i += 1
            if i >= n+1:
                n_to_last = n_to_last.next
            if i >= n+2:
                n_plus_1_to_last = n_plus_1_to_last.next
            head = head.next
        
        if i == n:
            return head_bak.next
        else:
            n_plus_1_to_last.next = n_to_last.next
            return head_bak
        

 

Idea

Maintain two pointers. One is pointing to (n+1) to the last element. The other is point to n to the last element. Be careful for the corner case when there are only n elements in total.

Another idea can be seen: https://discuss.leetcode.com/topic/7031/simple-java-solution-in-one-pass

Leetcode 200: Number of Islands

200. Number of Islands

  • Total Accepted: 71131
  • Total Submissions: 228449
  • Difficulty: Medium
  • Contributors: Admin

Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example 1:

11110
11010
11000
00000

Answer: 1

Example 2:

11000
11000
00100
00011

Answer: 3

 

Code

class Solution(object):
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        if not grid:
            return 0

        res = 0
        for i in xrange(len(grid)):
            for j in xrange(len(grid[0])):
                if grid[i][j] == '1':
                    res += 1
                    self.explore(grid, i, j)
        return res

    def explore(self, grid, i, j):
        grid[i][j] = "*"
        # down, up, right, left
        for di, dj in ((0, 1), (0, -1), (1, 0), (-1, 0)):
            if 0 <= i+di < len(grid) and 0 <= j+dj < len(grid[0]) \
                and grid[i+di][j+dj] == '1':
                    self.explore(grid, i+di, j+dj)

 

Idea

Whenever you see an 1, increment result by 1. The method explore visits adjacent 1’s in a DFS manner. Every visited cell will be re-marked so that no future visit will happen.

If the grid size is N^2, then the time complexity is O(N^2) and the space complexity is O(N^2) as well because DFS recursive calls can visit up to all cells and take O(N^2) stack frame.

Reference: https://discuss.leetcode.com/topic/11590/simple-java-solution

 

Leetcode 75: Sort Colors

75. Sort Colors

  • Total Accepted: 125210
  • Total Submissions: 345796
  • Difficulty: Medium
  • Contributors: Admin

Given an array with n objects colored red, white or blue, sort them 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.

click to show follow up.

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 an one-pass algorithm using only constant space?

Show Company Tags
Hide Tags

 

Code

class Solution(object):
    def sortColors(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        left, right = 0, len(nums)-1
        for i in xrange(len(nums)):
            while nums[i] == 2 and i < right:
                nums[i], nums[right] = nums[right], nums[i]
                right -= 1
            while nums[i] == 0 and i > left:
                nums[i], nums[left] = nums[left], nums[i]
                left += 1
            

 

Idea

Put all 2’s after `right`. Put all 1’s before `left`.

 

Reference: https://discuss.leetcode.com/topic/5422/share-my-one-pass-constant-space-10-line-solution