76. Minimum Window Substring

Created
Feb 4, 2024 12:15 PM
Modified
Last updated February 4, 2024
Tag
Leet Code
Hard
Daily Question
  • 두 λ¬Έμžμ—΄ s, t κ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ t에 μžˆλŠ” λͺ¨λ“  κΈ€μžλ₯Ό ν¬ν•¨ν•˜λŠ” s의 λΆ€λΆ„ λ¬Έμžμ—΄ 쀑 κ°€μž₯ 길이가 짧은 것을 κ΅¬ν•˜λŠ” 문제.
  • t에 μžˆλŠ” λͺ¨λ“  κΈ€μžλ₯Ό ν¬ν•¨ν•˜κΈ°λ§Œ ν•˜λ©΄ 되고 μˆœμ„œλŠ” 지킬 ν•„μš”κ°€ μ—†μœΌλ―€λ‘œ t 그리고 s의 λΆ€λΆ„ λ¬Έμžμ—΄μ— λŒ€ν•΄μ„œ μ†ν•΄μžˆλŠ” 문자의 μΆœν˜„ λΉˆλ„λ₯Ό μ„Έμ–΄μ„œ λΉ„κ΅ν•˜λ©΄ λœλ‹€.
    • λ¨Όμ € s의 길이가 t보닀 μž‘μœΌλ©΄ μ• μ΄ˆμ— t에 μ†ν•œ λͺ¨λ“  문자λ₯Ό 포함할 수 μ—†μœΌλ―€λ‘œ 닡이 μ—†λŠ” 것 β€œβ€ 으둜 ν•œλ‹€.
    • t에 μ†ν•œ 문자의 μΆœν˜„ λΉˆλ„λ₯Ό μ„Έμ–΄ μ €μž₯ tCntν•΄λ‘”λ‹€.
    • s의 μ΅œμ†Œ λΆ€λΆ„ λ¬Έμžμ—΄ λ²”μœ„ min을 [0, Integer.MAX_VALUE]둜 (Integer.MAX_VALUEλŠ” 값이 μ—†μŒμ„ ν‘œμ‹œν•˜κΈ° μœ„ν•΄), ν˜„μž¬ λΆ€λΆ„ λ¬Έμžμ—΄ λ²”μœ„ curλ₯Ό [0, 0]으둜 μ΄ˆκΈ°ν™”ν•œλ‹€.
    • λΆ€λΆ„ λ¬Έμžμ—΄ λ²”μœ„ cur을 λ‹€μŒκ³Ό 같은 κ·œμΉ™μœΌλ‘œ ν™•μž₯, μΆ•μ†Œν•˜λ©΄μ„œ 쑰건을 λ§Œμ‘±ν•˜λŠ” λ²”μœ„λ₯Ό μ°ΎλŠ”λ‹€.
      • λΆ€λΆ„ λ¬Έμžμ—΄μ˜ μΆœν˜„ λΉˆλ„ sCnt와 λŒ€μƒ λ¬Έμžμ—΄μ˜ μΆœν˜„ λΉˆλ„ tCnt λ₯Ό λΉ„κ΅ν•˜μ—¬ ν˜„μž¬ λΆ€λΆ„ λ¬Έμžμ—΄μ— λŒ€μƒ λ¬Έμžμ—΄μ΄ ν¬ν•¨λ˜λŠ”μ§€ 확인 containsν•œλ‹€.
      • ν¬ν•¨λ˜μ§€ μ•ŠλŠ” 경우 contains == false λΆ€λΆ„ λ¬Έμžμ—΄μ˜ λ²”μœ„λ₯Ό λ’·μͺ½μœΌλ‘œ ν™•μž₯ ++cur[1] ν•˜μ—¬ 더 λ§Žμ€ λ¬Έμžκ°€ λΆ€λΆ„ λ¬Έμžμ—΄μ— ν¬ν•¨λ˜λ„λ‘ ν•œλ‹€.
        • λ²”μœ„κ°€ ν™•μž₯λ˜μ—ˆμœΌλ―€λ‘œ μƒˆλ‘œ μΆ”κ°€λœ 문자 s.charAt(cur[1])λ₯Ό λΆ€λΆ„ λ¬Έμžμ—΄μ˜ μΆœν˜„ λΉˆλ„ λ°°μ—΄ sCnt에 μΆ”κ°€ ++sCnt[ordAt(s, cur[1])]ν•œλ‹€.
      • ν¬ν•¨λ˜λŠ” 경우 contains == true λΆ€λΆ„ λ¬Έμžμ—΄μ˜ λ²”μœ„λ₯Ό μ•žμͺ½μ—μ„œ μΆ•μ†Œ --cur[0] ν•˜μ—¬ 더 적은 λ¬Έμžμ—΄λ‘œλ„ 쑰건을 λ§Œμ‘±ν•  수 μžˆλŠ”μ§€ ν™•μΈν•œλ‹€.
        • λ²”μœ„κ°€ μΆ•μ†Œλ˜μ—ˆμœΌλ―€λ‘œ 제거된 문자 s.charAt(cur[0])λ₯Ό λΆ€λΆ„ λ¬Έμžμ—΄μ˜ μΆœν˜„ λΉˆλ„ λ°°μ—΄ sCntμ—μ„œ 제거 --sCnt[ordAt(s, cur[0])]ν•œλ‹€.
      • λ¬Έμžμ—΄μ˜ λ²”μœ„κ°€ 문자의 길이 M = s.length()λ₯Ό μ΄ˆκ³Όν•˜μ§€ μ•ŠλŠ” λ²”μœ„μ—μ„œ ν™•μž₯, μΆ•μ†Œλ₯Ό μ§„ν–‰ν•œλ‹€.
class Solution { final int L = 2 * ('z' - 'a' + 1); int ordAt(String s, int i) { if (i >= s.length()) { return 0; } int c = s.charAt(i); return c >= 'a' && c <= 'z'? c - 'a' : c - 'A' + L / 2; } public String minWindow(String s, String t) { int M = s.length(); int N = t.length(); if (M < N) return ""; int[] sCnt = new int[L]; int[] tCnt = new int[L]; for (int i = 0; i < N; ++i) { ++tCnt[ordAt(t, i)]; } int[] min = new int[]{ 0, Integer.MAX_VALUE }; int[] cur = new int[]{ 0, 0 }; while (cur[1] <= M) { int minLength = min[1] - min[0]; int length = cur[1] - cur[0]; boolean contains = true; for (int i = 0; i < L; ++i) { if (sCnt[i] < tCnt[i]) { contains = false; break; } } if (contains) { if (length < minLength) { min[0] = cur[0]; min[1] = cur[1]; } --sCnt[ordAt(s, cur[0])]; ++cur[0]; } else { ++sCnt[ordAt(s, cur[1])]; ++cur[1]; } } if (min[1] == Integer.MAX_VALUE) return ""; return s.substring(min[0], min[1]); } }