1. 程式人生 > 實用技巧 >【leetcode】1562. Find Latest Group of Size M

【leetcode】1562. Find Latest Group of Size M

題目如下:

Given an arrayarrthat represents a permutation of numbers from1ton. You have a binary string of sizenthat initially has all its bits set to zero.

At each stepi(assuming both the binary string andarrare 1-indexed) from1ton, the bit at positionarr[i]is set to1. You are given an integermand you need to find the latest step at which there exists a group of ones of lengthm

. A group of ones is a contiguous substring of 1s such that it cannot be extended in either direction.

Returnthe latest step at which there exists a group of ones of lengthexactlym.If no such group exists, return-1.

Example 1:

Input: arr = [3,5,1,2,4], m = 1
Output: 4
Explanation:
Step 1: "00100", groups: ["1"]
Step 2: "00101
", groups: ["1", "1"] Step 3: "10101", groups: ["1", "1", "1"] Step 4: "11101", groups: ["111", "1"] Step 5: "11111", groups: ["11111"] The latest step at which there exists a group of size 1 is step 4.

Example 2:

Input: arr = [3,1,5,4,2], m = 2
Output: -1
Explanation:
Step 1: "00100", groups: ["1"]
Step 2: "1
0100", groups: ["1", "1"] Step 3: "10101", groups: ["1", "1", "1"] Step 4: "10111", groups: ["1", "111"] Step 5: "11111", groups: ["11111"] No group of size 2 exists during any step.

Example 3:

Input: arr = [1], m = 1
Output: 1

Example 4:

Input: arr = [2,1], m = 2
Output: 2

Constraints:

  • n == arr.length
  • 1 <= n <= 10^5
  • 1 <= arr[i] <= n
  • All integers inarraredistinct.
  • 1 <= m<= arr.length

解題思路:我的思路是將把每個group的起始索引和結束索引記錄到一個數組sub_range裡面,sub_range的初始值為[[1,max(arr)]],然後倒序處理arr,根據arr[i]的值對sub_range進行拆分,每做一次拆分,計算更新後的sub_range是否有某個元素的range的長度正好為m。

程式碼如下:

class Solution(object):
    def findLatestStep(self, arr, m):
        """
        :type arr: List[int]
        :type m: int
        :rtype: int
        """
        sub_range = [[1,max(arr)]]

        def binarySearch(a, l, r, x):
            if r >= l:
                mid = int(l + (r - l) / 2)
                if a[mid][0] <= x and a[mid][1] >= x:
                    return mid
                elif a[mid][0] > x:
                    return binarySearch(a, l, mid - 1, x)
                elif a[mid][1] < x:
                    return binarySearch(a, mid + 1, r, x)
            else:
                return -1


        if len(arr) == m:return m

        for i in range(len(arr)-1,-1,-1):
            mid = binarySearch(sub_range,0,len(sub_range)-1,arr[i])
            if mid == -1:continue
            if sub_range[mid][1] == sub_range[mid][0]:
                del sub_range[mid]
                continue
            end = sub_range[mid][1]
            sub_range[mid][1] = arr[i] - 1
            if end - (arr[i]+1) >= m:
                sub_range.insert(mid+1,[arr[i]+1,end])
            if sub_range[mid][1] - sub_range[mid][0] + 1 == m or  end - (arr[i]+1) + 1 == m:
                return i
            if sub_range[mid][1] - sub_range[mid][0] < m:
                del sub_range[mid]
                continue
        return -1