907. Sum of Subarray Minimums

Created
Jan 20, 2024 09:26 AM
Modified
Last updated January 20, 2024
Tag
Leet Code
Medium
Daily Question
  • μ£Όμ–΄μ§„ λ°°μ—΄ arrarr 의 λͺ¨λ“  μ—°μ†λœ λΆ€λΆ„ λ°°μ—΄ Aij=[ arr[i], arr[i+1], ..., arr[j] ]  (0≀i≀j<N)A_{ij} = [\,arr[i], \,arr[i+1], \, ..., \, arr[j]\,] \,\, (0 ≀ i ≀ j < N)에 λŒ€ν•΄μ„œ κ·Έ μ΅œμ†Œκ°’ min(Aij)min(A_{ij})의 ν•© S=βˆ‘i=0Nβˆ’1βˆ‘j=iNβˆ’1 min(Aij)S = \sum\limits_{i=0}^{N-1}\sum\limits_{j=i}^{N-1}\,min(A_{ij}) 을 κ΅¬ν•˜λŠ” 문제.
    • κ²°κ³Ό 값이 맀우 클 수 μžˆμœΌλ―€λ‘œ 109+710^9 + 7둜 λ‚˜λ¨Έμ§€ 연산을 μˆ˜ν–‰ν•΄μ„œ λŒλ €μ£Όμ–΄μ•Ό ν•œλ‹€.
  • λ‹¨μˆœν•˜κ²Œ μ ‘κ·Όν•œλ‹€λ©΄ 각 λ²”μœ„ [i,j][i, j] λ³„λ‘œ μ΅œμ†Œκ°’μ„ κ΅¬ν•˜λŠ” 방식을 μ·¨ν•  수 μžˆμ„ 것이닀. λ‹€λ§Œ μ΄λ ‡κ²Œ ν•˜λ©΄ μ‹œκ°„ λ³΅μž‘λ„κ°€ O(N2)O(N^2)이 λ˜λ―€λ‘œ μ‹œκ°„ μ œν•œμ„ μ΄ˆκ³Όν•˜κ²Œ λœλ‹€.
  • 배열을 ν•œλ²ˆλ§Œ μˆœνšŒν•˜λ©΄μ„œ 값을 κ³„μ‚°ν•˜κΈ° μœ„ν•΄μ„œ λΆ€λΆ„ λ°°μ—΄μ˜ μ΅œμ†Œκ°’ κ·œμΉ™μ„ λ°œκ²¬ν•  ν•„μš”κ°€ μžˆλ‹€.
e.g. arr = [3, 2, 4, 1] 이라고 κ°€μ •ν•˜μž. 각 λΆ€λΆ„ λ°°μ—΄ 별 μ΅œμ†Œκ°’μ„ κ΅¬ν•˜λ©΄ μ•„λž˜μ™€ κ°™λ‹€. - index = 0 - sub array: [3], [3, 2], [3, 2, 4], [3, 2, 4, 1] - min value: 3, 2, 2, 1 - index = 1 - sub array: [2], [2, 4], [2, 4, 1] - min value: 2, 2, 1 - index = 2 - sub array: [4], [4, 1] - min value: 4, 1 - index = 3 - sub array: [1] - min value: 1
  • μœ„μ˜ 결과둜 λΆ€ν„° λ‹€μŒκ³Ό 같은 λ‘œμ§μ„ λ„μΆœν•  수 μžˆλ‹€.
    • λ°°μ—΄ arrarr에 μΆœν˜„ν•œ 값을 ν•˜λ‚˜μ”© μˆœνšŒν•˜λ©΄μ„œ μƒˆλ‘œμš΄ λ°°μ—΄ arr’arr’에 λ„£λŠ”λ‹€.
    • ν˜„μž¬ κ°’ ai=arr[i]a_i = arr[i]에 λŒ€ν•˜μ—¬,
      • arr’arr’에 μžˆλŠ” κ°’ 쀑 aia_i 보닀 큰 λͺ¨λ“  값은 aia_i둜 λŒ€μ²΄ν•œλ‹€.
      • arr’arr’에 μžˆλŠ” κ°’ 쀑 aia_i 보닀 μž‘μ€ λͺ¨λ“  값은 κ·ΈλŒ€λ‘œ λ‘”λ‹€.
    • arr’arr’에 값을 ν•˜λ‚˜ 넣을 λ•Œ λ§ˆλ‹€ arr’arr’에 μžˆλŠ” λͺ¨λ“  값을 κ²°κ³Ό 값에 λ”ν•œλ‹€.
  • 둜직 μˆ˜ν–‰ν–ˆμ„ λ•Œ arr’arrβ€™μ˜ μƒνƒœμ„ μ‹œκ°ν™”ν•˜λ©΄ μ•„λž˜μ™€ κ°™λ‹€.
e.g. arr = [3, 2, 4, 1] 이라고 ν•  λ•Œ, - index = 0 β†’ [3] - index = 1 β†’ [3 β†’ 2, 2] β†’ [2, 2] - index = 2 β†’ [2, 2, 4] - index = 3 β†’ [2 β†’ 1, 2 β†’ 1, 4 β†’ 1, 1] β†’ [1, 1, 1, 1]
  • arr’arrβ€™μ˜ 값을 μ €μž₯ν•˜κΈ° μœ„ν•΄μ„œ μŠ€νƒμ„ μ‚¬μš©ν•˜λ©΄ μœ„μ˜ λ‘œμ§μ„ μ‰½κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€.
    • λ¬Έμ œλŠ” μŠ€νƒμ„ μ‚¬μš©ν–ˆμ„ λ•Œ λͺ¨λ“  값을 μˆœνšŒν•˜λ©΄μ„œ λ”ν•œλ‹€λ©΄ μ΅œμ•…μ˜ κ²½μš°μ—λŠ” μ‹œκ°„ λ³΅μž‘λ„κ°€ O(N2)O(N^2)이 될 수 μžˆλ‹€.
    • arrarr의 값이 단쑰 증가 ai≀aj (i<j)a_i ≀ a_j \, (i < j) ν•  경우 μ œκ±°λ˜λŠ” 값이 없이 λͺ¨λ“  값이 μŠ€νƒμ— μΆ”κ°€λ˜λ―€λ‘œ μŠ€νƒμ˜ ν¬κΈ°λŠ” O(N)O(N)이 되기 λ•Œλ¬Έμ΄λ‹€.
    • λ§€ index λ§ˆλ‹€ O(N)O(N)의 μ‹œκ°„ λ³΅μž‘λ„λ‘œ 값을 더해야 ν•˜κΈ°μ— 결과적으둜 μ‹œκ°„ λ³΅μž‘λ„λŠ” O(N2)O(N^2)κ°€ λœλ‹€.
  • λ”°λΌμ„œ μŠ€νƒμ— λ“€μ–΄κ°€ μžˆλŠ” κ°’μ˜ 합을 λ³„λ„μ˜ λ©”λͺ¨λ¦¬ currSum둜 μΆ”μ ν•œλ‹€λ©΄ 이 μ‹œκ°„μ„ μ•„λ‚„ 수 μžˆλ‹€.
    • μƒˆλ‘­κ²Œ 값이 μΆ”κ°€λ˜λ©΄ currSum에 λ”ν•œλ‹€.
    • 기쑴에 μžˆλŠ” 값을 μ œκ±°ν•  λ•ŒλŠ” currSumμ—μ„œ λΊ€λ‹€.
  • λ˜ν•œ λ™μΌν•œ 값을 μŠ€νƒμ— 각각 λ„£λŠ” λŒ€μ‹ , 숫자 & ν•΄λ‹Ή 숫자의 μΆœν˜„ λΉˆλ„λ₯Ό μ €μž₯ν•˜λŠ” 것이 쒋을 것이닀.
e.g. arr = [3, 2, 4, 1] 이라고 ν•  λ•Œ, μŠ€νƒμ— [숫자, 숫자의 μΆœν˜„ λΉˆλ„] 둜 μ €μž₯ν•œλ‹€. <λ°”κΎΈκΈ° μ „> - index = 0 β†’ [3] - index = 1 β†’ [2, 2] - index = 2 β†’ [2, 2, 4] - index = 3 β†’ [1, 1, 1, 1] <λ°”κΎΌ ν›„> - index = 0 β†’ [[3, 1]] - index = 1 β†’ [[2, 2]] - index = 2 β†’ [[2, 2], [4, 1]] - index = 3 β†’ [[1, 4]]
class Solution { public static final int MOD = 1_000_000_000 + 7; public int sumSubarrayMins(int[] arr) { int N = arr.length; Stack<int[]> stack = new Stack<>(); int currSum = arr[0]; int sum = currSum; stack.push(new int[]{ arr[0], 1 }); for (int i = 1; i < N; ++i) { int count = 1; while (!stack.empty()) { int[] last = stack.peek(); if (last[0] < arr[i]) break; stack.pop(); count += last[1]; currSum = (currSum - last[0] * last[1]) % MOD; } int[] newPair = new int[]{ arr[i], count }; stack.push(newPair); currSum = (currSum + newPair[0] * newPair[1]) % MOD; sum = (sum + currSum) % MOD; } return sum; } }