Potato
์•ˆ๋…•ํ•˜์„ธ์š”, ๊ฐ์žก๋‹ˆ๋‹ค?๐Ÿฅ” ^___^ ๐Ÿ˜บ github ๋ฐ”๋กœ๊ฐ€๊ธฐ ๐Ÿ‘‰๐Ÿป

Algorithm/Programmers

[ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค] (Swift) Kakao - ๋ฉ”๋‰ด ๋ฆฌ๋‰ด์–ผ

๊ฐ์ž ๐Ÿฅ” 2022. 5. 12. 17:47
๋ฐ˜์‘ํ˜•

๋ฌธ์ œ ๋งํฌ

https://programmers.co.kr/learn/courses/30/lessons/72411

 

์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์—ฐ์Šต - ๋ฉ”๋‰ด ๋ฆฌ๋‰ด์–ผ

๋ ˆ์Šคํ† ๋ž‘์„ ์šด์˜ํ•˜๋˜ ์Šค์นดํ”ผ๋Š” ์ฝ”๋กœ๋‚˜19๋กœ ์ธํ•œ ๋ถˆ๊ฒฝ๊ธฐ๋ฅผ ๊ทน๋ณตํ•˜๊ณ ์ž ๋ฉ”๋‰ด๋ฅผ ์ƒˆ๋กœ ๊ตฌ์„ฑํ•˜๋ ค๊ณ  ๊ณ ๋ฏผํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์—๋Š” ๋‹จํ’ˆ์œผ๋กœ๋งŒ ์ œ๊ณตํ•˜๋˜ ๋ฉ”๋‰ด๋ฅผ ์กฐํ•ฉํ•ด์„œ ์ฝ”์Šค์š”๋ฆฌ ํ˜•ํƒœ๋กœ ์žฌ๊ตฌ์„ฑํ•ด์„œ

programmers.co.kr

 

๋ฌธ์ œ ์„ค๋ช…

  • ์ž…์ถœ๋ ฅ[์˜ˆ]๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค 
  • orders
    • orders์— ์‚ฌ๋žŒ๋“ค์ด ์ฃผ๋ฌธํ•œ ์ฃผ๋ฌธ๋‚ด์—ญ์ด ๋“ค์–ด์žˆ๋‹ค. ์ž…์ถœ๋ ฅ ์˜ˆ์‹œ 1๋ฒˆ์œผ๋กœ ๋ณด๋ฉด 6๋ช…์˜ ์‚ฌ๋žŒ๋“ค์ด ์ฃผ๋ฌธํ–ˆ๋‹ค.
    • ์ฒซ๋ฒˆ์งธ ์‚ฌ๋žŒ์€ "ABCFG" ๋ฉ”๋‰ด๋ฅผ ์ฃผ๋ฌธํ–ˆ๋‹ค. A๋ฉ”๋‰ด, B๋ฉ”๋‰ด,,,,
  • course
    • ์ฃผ์ธ๊ณต '์Šค์นดํ”ผ'๋Š” ์ฝ”์Šค๋ฉ”๋‰ด๋ฅผ ๊ตฌ์„ฑ์ค‘์ด๋‹ค.
    • [2, 3, 4] ๋ผ๋Š” ์˜๋ฏธ๋Š”, 2๊ฐ€์ง€ ๋ฉ”๋‰ด๋กœ ๊ตฌ์„ฑ๋œ ์ฝ”์Šค, 3๊ฐ€์ง€ ๋ฉ”๋‰ด๋กœ ๊ตฌ์„ฑ๋œ ์ฝ”์Šค,,, ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค๊ฒ ๋‹ค๋Š” ๋œป์ด๋‹ค.
    • ์ฝ”์Šค์š”๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์กฐ๊ฑด๋„ ์žˆ๋‹ค.
      • ์ฝ”์Šค์š”๋ฆฌ๋Š” ์ตœ์†Œ 2๋ช… ์ด์ƒ์˜ ์†๋‹˜์œผ๋กœ ๋ถ€ํ„ฐ ์ฃผ๋ฌธ๋œ ๋‹จํ’ˆ๋ฉ”๋‰ด ์กฐํ•ฉ์— ๋Œ€ํ•ด์„œ๋งŒ ์ฝ”์Šค์š”๋ฆฌ ๋ฉ”๋‰ด ํ›„๋ณด์— ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค.
      • ์ด ์„ค๋ช…์€ ๋ฐ”๋กœ ์•„๋ž˜ ์žˆ๋Š” ์‚ฌ์ง„์„ ๋ณด๋ฉด ์ดํ•ด๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.

  • result
    • ์ฃผ์ธ๊ณต '์Šค์นดํ”ผ'๊ฐ€ ๊ตฌ์„ฑํ•˜๊ฒŒ๋  ๋ฉ”๋‰ด์˜ ๊ตฌ์„ฑ์„ return ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฐ์—ด์ด๋‹ค.
    • ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ๋ฆฌํ„ดํ•ด์•ผํ•œ๋‹ค.

 

๋‚ด๊ฐ€ ํ‘ผ ํ’€์ด (์ฐธ๊ณ ํ•œ ํ’€์ด ๐Ÿฅฒ)

  • dfs ๋จผ์ € ๋งŒ๋“ค์ž
  • ๋‚ด๊ฐ€ ๋งŒ๋“œ๋ ค๊ณ  ํ•˜๋Š” course ์˜์ตœ๋Œ€ ๊ธธ์ด๋ณด๋‹ค, string(๋ฉ”๋‰ด๊ตฟ๊ฒ…)์ด ๊ธธ์–ด์งˆ ๊ฒฝ์šฐ์—๋Š” ๊ณ ๋ คํ•˜์ง€ ์•Š๋Š”๋‹ค.
func dfs(index: Int, origin: [Character], newString: String) {
	// ๊ตฌํ•˜๋ ค๋Š” ์ฝ”์Šค ๊ธธ์ด๋ณด๋‹ค, string(์ƒˆ๋กœ์šด ๋ฉ”๋‰ด ๊ตฌ์„ฑ)์ด ๋” ๊ธธ๋‹ค๋ฉด ๊ณ ๋ คํ•˜์ง€ ์•Š์Œ
    if course.last! < newString.count{
        return
    }
	
    // string(์ƒˆ๋กœ์šด ๋ฉ”๋‰ด ๊ตฌ์„ฑ)์ด set(๋ฉ”๋‰ด๊ฐœ์ˆ˜: ๋“ฑ์žฅํšŸ์ˆ˜)์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธ
    // ์กด์žฌํ•œ๋‹ค๋ฉด += 1
    // ์กด์žฌํ•˜์ง€ ์•Š๋‹ค๋ฉด ๋ฉ”๋‰ด ์ž์ฒด๋ฅผ set ์— ์ถ”๊ฐ€ํ•ด์คŒ
    if course.contains(newString.count) {
        if set.keys.contains(newString) {
            set[newString]! += 1
        } else {
            set[newString] = 1
        }
    }

	// dfs index 0๋ถ€ํ„ฐ ๋Œ๋ ค์„œ ์žฌ๊ท€๋กœ ์ฐพ์„ ๊ฒƒ
    for i in index..<origin.count {
        let c = origin[i]
        dfs(index: i+1, origin:  origin, newString: "\(newString)\(c)")
    }
}

 

  • dfs ํƒ์ƒ‰ ์‹œ์ž‘
  • orders ๋กœ๋ถ€ํ„ฐ ์ฃผ๋ฌธ์„ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด์„œ sorted๋กœ ์ •๋ฆฌํ•ด์ฃผ๊ณ , ๊ฐ๊ฐ dfs๋Œ๋ ค์ฃผ๋ฉด์„œ ์Œ์‹ ์กฐํ•ฉ์„ ๋งŒ๋“ค์–ด์ค€๋‹ค
for order in orders {
    let order = order.sorted()
    dfs(index: 0, origin: order, newString: "")
    // print("order = \(order), set = \(set)")
    // print("----------------------")
}

์ด๋ ‡๊ฒŒ ํ•˜๊ฒŒ ๋˜๋ฉด,  ์•„๋ž˜ ์‚ฌ์ง„์ฒ˜๋Ÿผ ํ•ด๋‹น order ์—์„œ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๋ฉ”๋‰ด๊ตฌ์„ฑ์ด ๋“ฑ์žฅ

 

  • ์ด์ œ ์œ„ ๋ฉ”๋‰ด ๊ตฌ์„ฑ(set)์—์„œ , 2๋ฒˆ ์ด์ƒ ์„ ํƒ๋ฐ›์€ ๋ฉ”๋‰ด๋งŒ ์„ ์ •ํ•ด์ค€๋‹ค.
  • ์ตœ๋Œ“๊ฐ’์ด ๊ฐ™์œผ๋ฉด ๋ชจ๋‘ ํฌํ•จํ•ด์•ผํ•œ๋‹ค! (4๋ฒˆ๋“ฑ์žฅํ•œ ๋ฉ”๋‰ด๊ฐ€ "AB", "CD" ์ด๋ฉด ๋‘˜๋‹ค ํฌํ•จํ•ด์•ผํ•œ๋‹ค๋Š” ๋œป)
var result = [String]()
    
for length in course {
    let temp = set.filter { $0.key.count == length && $0.value > 1 }
    let maxNum = temp.max { $0.value < $1.value }
    let menu = temp.filter { maxNum!.value == $0.value }.map { $0.key }
    result.append(contentsOf: menu)
}

// return result.sorted() -> ์ตœ์ข…์ ์œผ๋กœ sorted๋œ ๊ฐ’์„ return

 

 

์ตœ์ข… ์ฝ”๋“œ

import Foundation

//result = ["AC", "ACDE", "BCFG", "CDE"]
var orders = ["ABCFG", "AC", "CDE", "ACDE", "BCFG", "ACDEH"]
var course = [2,3,4]

func solution(_ orders:[String], _ course:[Int]) -> [String] {
    var set = [String: Int]()
    
    func dfs(index: Int, origin: [Character], newString: String) {
        if course.last! < newString.count{
            return
        }
        
        if course.contains(newString.count) {
            if set.keys.contains(newString) {
                set[newString]! += 1
            } else {
                set[newString] = 1
            }
        }
        
        for i in index..<origin.count {
            let c = origin[i]
            dfs(index: i+1, origin:  origin, newString: "\(newString)\(c)")
        }
    }
    
    // ํƒ์ƒ‰์‹œ์ž‘
    for order in orders {
        let order = order.sorted()
        dfs(index: 0, origin: order, newString: "")
//        print("order = \(order), set = \(set)")
//        print("----------------------")
    }
    // ์กฐํ•ฉ์ค‘ 2๋ฒˆ์ด์ƒ ์„ ํƒ๋ฐ›์€ ๋ฉ”๋‰ด๋งŒ ๊ฐ€๋Šฅ
    // ์ตœ๋Œ€๊ฐ’์ด ๊ฐ™์œผ๋ฉด ๋ชจ๋‘ํฌํ•จ
    var result = [String]()
    
    for length in course {
        let temp = set.filter { $0.key.count == length && $0.value > 1 }
        let maxNum = temp.max { $0.value < $1.value }
        let menu = temp.filter { maxNum!.value == $0.value }.map { $0.key }
        result.append(contentsOf: menu)
    }
    return result.sorted()
    
}

print(solution(orders, course))
๋ฐ˜์‘ํ˜•