|
| 1 | +/** |
| 2 | + * Question Link: https://leetcode.com/problems/subarrays-with-k-different-integers/ |
| 3 | + * Primary idea: Sliding window. |
| 4 | + * Assuming i1 < i2 < i3, (i1,j) and (i3,j) are valid, (i2,j) is definitely valid. |
| 5 | + * However, assuming i3 < i4, (i4,j) is is only invalid when the distance between i4 and j is less than k. |
| 6 | + * Using 2 sliding windows could solve the problem. |
| 7 | + * |
| 8 | + * Time Complexity: O(n), Space Complexity: O(n) |
| 9 | + * |
| 10 | + */ |
| 11 | + |
| 12 | +class SubarraysKDifferentIntegers { |
| 13 | + func subarraysWithKDistinct(_ nums: [Int], _ k: Int) -> Int { |
| 14 | + var left1 = 0, left2 = 0, window1 = Window(), window2 = Window(), uniqueSubarrayCount = 0 |
| 15 | + |
| 16 | + for right in 0..<nums.count { |
| 17 | + let num = nums[right] |
| 18 | + window1.add(num) |
| 19 | + window2.add(num) |
| 20 | + |
| 21 | + while window1.uniqueNum > k { |
| 22 | + window1.remove(nums[left1]) |
| 23 | + left1 += 1 |
| 24 | + } |
| 25 | + |
| 26 | + while window2.uniqueNum >= k { |
| 27 | + window2.remove(nums[left2]) |
| 28 | + left2 += 1 |
| 29 | + } |
| 30 | + |
| 31 | + uniqueSubarrayCount += (left2 - left1) |
| 32 | + } |
| 33 | + |
| 34 | + return uniqueSubarrayCount |
| 35 | + } |
| 36 | + |
| 37 | + class Window { |
| 38 | + var uniqueNum = 0 |
| 39 | + private var numFreq = [Int: Int]() |
| 40 | + |
| 41 | + func add(_ num: Int) { |
| 42 | + numFreq[num, default: 0] += 1 |
| 43 | + if numFreq[num] == 1 { |
| 44 | + uniqueNum += 1 |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | + func remove(_ num: Int) { |
| 49 | + if let freq = numFreq[num] { |
| 50 | + numFreq[num] = freq - 1 |
| 51 | + |
| 52 | + if freq == 1 { |
| 53 | + uniqueNum -= 1 |
| 54 | + } |
| 55 | + } |
| 56 | + } |
| 57 | + } |
| 58 | +} |
| 59 | + |
0 commit comments