From 2af783bc9cb5181066206e6b6841d6d7880a9009 Mon Sep 17 00:00:00 2001 From: Yi Gu Date: Sun, 1 Dec 2019 01:55:27 -0800 Subject: [PATCH] [String] Add a solution to Find the Closest Palindrome --- DP/BestTimeBuySellStockIV.swift | 6 ++- README.md | 3 +- String/FindClosestPalindrome.swift | 69 ++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 String/FindClosestPalindrome.swift diff --git a/DP/BestTimeBuySellStockIV.swift b/DP/BestTimeBuySellStockIV.swift index 1746b23d..3d204762 100644 --- a/DP/BestTimeBuySellStockIV.swift +++ b/DP/BestTimeBuySellStockIV.swift @@ -21,7 +21,11 @@ return makeMaxProfit(prices) } - var local = Array(repeating: 0, count: k + 1), global = Array(repeating: 0, count: k + 1) + // local[i] means the maxProfit when sell happens at ith day + var local = Array(repeating: 0, count: k + 1) + + // global[i] means the maxProfit at ith day + var global = Array(repeating: 0, count: k + 1) for i in 0.. String { + let chars = Array(n) + var candidates = Set() + + candidates.insert(buildLeftNum(n)) + candidates.insert(buildRightNum(n)) + + for distance in -1...1 { + candidates.insert(buildPalindromeOnMiddle(chars, distance)) + } + + return findNearest(n, candidates) + } + + private func buildLeftNum(_ num: String) -> String { + return String(repeating: "9", count: num.count - 1) + } + + private func buildRightNum(_ num: String) -> String { + return "1" + String(repeating: "0", count: num.count - 1) + "1" + } + + private func buildPalindromeOnMiddle(_ n: [Character], _ distance: Int) -> String { + let middleIdx = n.count % 2 == 0 ? n.count / 2 - 1: n.count / 2 + let leftPart = String(Int(String(n[0...middleIdx]))! + distance) + + if n.count % 2 != 0 { + return String(leftPart.dropLast() + leftPart.reversed()) + } else { + return String(leftPart + leftPart.reversed()) + } + } + + private func findNearest(_ n: String, _ candidates: Set) -> String { + guard let num = Int(n) else { + fatalError("Invalid Input") + } + + var nearest = 0 + + for candidate in candidates { + guard let cNum = Int(candidate) else { + continue + } + if cNum == num { + continue + } + + if abs(cNum - num) < abs(nearest - num) { + nearest = cNum + } else if abs(cNum - num) == abs(nearest - num) { + nearest = min(cNum, nearest) + } + } + + return String(nearest) + } +} \ No newline at end of file