[LV.1] 크기가 작은 부분 문자열

Heedon Ham·2024년 5월 22일
0
post-thumbnail

숫자로 이루어진 문자열 t와 p가 주어질 때, t에서 p와 길이가 같은 부분문자열 중에서, 이 부분문자열이 나타내는 수가 p가 나타내는 수보다 작거나 같은 것이 나오는 횟수를 return하는 함수 solution을 완성하세요.

제한사항

  • 1 ≤ p의 길이 ≤ 18
  • p의 길이 ≤ t의 길이 ≤ 10,000
  • t와 p는 숫자로만 이루어진 문자열이며, 0으로 시작하지 않습니다.

입출력 예

tpresult
"3141592""271"2
"500220839878""7"8
"10203""15"3

t ="3141592"이고 p ="271" 인 경우, t의 길이가 3인 부분 문자열은 314, 141, 415, 159, 592입니다. 이 문자열이 나타내는 수 중 271보다 작거나 같은 수는 141, 159 2개 입니다.


  1. t에서 p 자리수만큼 숫자들을 임시 생성, 이를 위해 각 시작점 위치 역할을 위한 정수 배열 생성
  2. String 타입이므로 prefix로 마지막 지점을 먼저 지정, suffix는 p의 자리수를 적용해 동일한 자리수를 가지도록 함
  3. Int type으로 변환, p보다 작거나 같으면 1, 크다면 0으로 값 할당 by map 함수
  4. reduce 함수로 각 배열의 element 더해서 결과값 도출
import Foundation

func solution(_ t:String, _ p:String) -> Int {
    return Array(0...t.count-p.count).map { Int(t.prefix(p.count+$0).suffix(p.count))! <= Int(p)! ? 1 : 0 }.reduce(0, +)
}

예상 문제점: map 함수 와중에 prefix, suffix 적용으로 O(mn)O(mn), 최악의 경우, O(n2)O(n^2)가 예측됨


Prefix, Suffix Complexity

O(1) if the collection conforms to RandomAccessCollection; otherwise, O(k), where k is the number of elements to select from the beginning of the collection.

O(1) if the collection conforms to RandomAccessCollection; otherwise, O(k), where k is equal to maxLength.


참고

String Index를 직접 구해서 해결하기

import Foundation

func solution(_ t:String, _ p:String) -> Int {
	//1. String.Index(utf16Offset:in:) 활용
    return (0..<t.count - p.count + 1).map { Int(t[String.Index(utf16Offset: $0, in: t)..<String.Index(utf16Offset: $0 + p.count, in: t)]) ?? 0 }.filter { Int(p)! >= $0 }.count
    
    //2. index(_:offsetBy:) 활용
    return (0..<t.count - p.count + 1).map { Int(t[t.index(t.startIndex, offsetBy: $0)..<t.index(t.startIndex, offsetBy: $0 + p.count)])! }.filter { Int(p)! >= $0 }.count
}

swift의 String 타입은 직접적으로 Int 타입을 통한 subscript를 활용해 해당 element를 찾을 수 없으므로, String.Index를 구해서 활용한다.

profile
dev( iOS, React)

0개의 댓글