1. 程式人生 > >Google面試題專題7 - leetcode930. Binary Subarrays With Sum/228. Summary Ranges

Google面試題專題7 - leetcode930. Binary Subarrays With Sum/228. Summary Ranges

930. Binary Subarrays With Sum

題目描述

陣列A僅包含0和1,有多少和為S的非空子陣列。

例子

Input: A = [1,0,1,0,1], S = 2
Output: 4

Explanation:
The 4 subarrays are bolded below:
[1,0,1]
[1,0,1]
[0,1,0,1]
[1,0,1]

思想

非空子陣列,起始位置為i,截止位置為j,暴力先求字首陣列和,再取差值作為A[i:j]的和,時間複雜度O(n^2)。

因為陣列只包含0和1,所以可以觀察出陣列的字首和是一遞增序列

。需要在該序列中找到兩數差值為S,想到2Sum

建一個字典,記錄當前不同字首和的數量。
dic[i]表示和為i的字首個數,sum[i]表示到i的字首和。
若當前座標是j,則目標是計算j之前共有多少個字首和等於sum[j] - S,即dic[sum[j] - S]。

解法1
暴力,TLE

class Solution(object):
    def numSubarraysWithSum(self, A, S):
        """
        :type A: List[int]
        :type S: int
        :rtype: int
        """
n = len(A) summ= [0] * (n+1) for i in range(1, n+1): summ[i] = summ[i-1] + A[i-1] cnt = 0 for i in range(n+1): for j in range(i+1, n+1): if summ[j] - summ[i] == S: cnt += 1 return cnt

(改進)

class Solution(object):
    def numSubarraysWithSum(self, A, S):
        """
        :type A: List[int]
        :type S: int
        :rtype: int
        """
        cnt = summ = 0
        dic = {0:1}
        for num in A:
            summ += num
            if summ - S in dic:
                cnt += dic[summ-S]
            if summ in dic:
                dic[summ] += 1
            else:
                dic[summ] = 1
        return cnt   

簡潔

class Solution(object):
    def numSubarraysWithSum(self, A, S):
        """
        :type A: List[int]
        :type S: int
        :rtype: int
        """
        cnt = summ = 0
        dic = {0:1}
        for num in A:
            summ += num
            cnt += dic.get(summ - S, 0)
            dic[summ] = dic.get(summ, 0) + 1
        return cnt   

228. Summary Ranges - Easy

題目描述

給定無重複的有序整數陣列,將其拆成連續的範圍。

例子
Example 1:

Input: [0,1,2,4,5,7]
Output: [“0->2”,“4->5”,“7”]

Explanation: 0,1,2 form a continuous range; 4,5 form a continuous range.

Example 2:

Input: [0,2,3,4,6,8,9]
Output: [“0”,“2->4”,“6”,“8->9”]

Explanation: 2,3,4 form a continuous range; 8,9 form a continuous range.

思想
因為陣列已排好序,所以遍歷一遍判斷並存儲結果即可。
Trick:’->’.join(map(str, p))
解法
最笨拙直接的方法

class Solution(object):
    def summaryRanges(self, nums):
        """
        :type nums: List[int]
        :rtype: List[str]
        """
        if not nums:
            return []
        res = []
        temp = [nums[0], nums[0]]
        for num in nums[1:]:
            if num == temp[-1] + 1:
                temp[-1] = num
            else:
                if temp[0] == temp[1]:
                    res.append(str(temp[0]))
                else:
                    res.append('%s->%s'%(temp[0], temp[1]))
                temp = [num, num]
                
        if temp[0] == temp[1]:
            return res + [str(temp[0])]
        return res + ['%s->%s'%(temp[0], temp[1])]

簡化程式碼:最後一起新增’->’

class Solution(object):
    def summaryRanges(self, nums):
        """
        :type nums: List[int]
        :rtype: List[str]
        """
        res = []
        for num in nums:
            if res and num == res[-1][-1] + 1:
                res[-1] = [res[-1][0], num]
            else:
                res.append([num])
        return ['->'.join(map(str, p)) for p in res]