1. 小于n的最大数(字节真题)
题目要求:给定一个数n如23121;给定一组数字a如[2 4 9]求由a中元素组成的小于n的最大数
思路:来自这里
先按目标数N的位数从高位到低位找,如果在数组中能找到与某位数相等的数,则将其推进数组,如果没找到,则从数组剩余数里面挑其次,有其次就找其次,且从该位开始后面可以直接push数组中最大的数了;如果没有其次,那么说明需要回退上一位(pop),找到上一位的其次,循环直到res拿到结果,走 break 跳出循环。
func maxNumber(_ n: Int, _ set: [Int]) -> Int {
var digits = [Int]()
var n = n
while n != 0 {
digits.insert(n % 10, at: 0)
n = n / 10
}
// 在set里面 优先找等于当前数字, 否则找次小的
// 都不满足(set里没有比当前数 更小的数了)返回 -1
func findSuitNum(_ n: Int) -> Int {
for i in (0..<set.count).reversed() {
if set[i] <= n { return set[i] }
}
return -1
}
var fixIndex = 0
// 是否寻找次小数
var findMax = true
while fixIndex != digits.count {
let num = digits[fixIndex]
// 最后一位强制查询次小数
if fixIndex == digits.count - 1 {
findMax = false
}
let suitN = findSuitNum(findMax ? num : num - 1)
findMax = true
if suitN == -1 {
// 没找到,则回退上一位 去找次小数
fixIndex -= 1
// 最高位就没找到直接break
if fixIndex < 0 {
break
} else {
findMax = false
}
} else if suitN == num {
// 找到当前数,找下一位
fixIndex += 1
} else if suitN < num {
// 只能找到次小数,直接退出,准备补充最大数
digits[fixIndex] = suitN
fixIndex += 1
break;
}
}
if fixIndex > 0 {
for i in fixIndex..<digits.count {
digits[i] = set.last!
}
} else {
// 最高位最后用不了。 除了本身最高位找不到,还存在回退的情况 2111 [2, 7, 9]
let size = digits.count
digits.removeAll()
for _ in 0..<(size - 1) {
digits.append(set.last!)
}
}
var res = 0
for (i, num) in digits.enumerated() {
res += num * ( pow(10, digits.count - i - 1) as NSDecimalNumber).intValue
}
return res
}
_ = maxNumber(777, [1, 4, 7])
// 这些case都能通过
//n=23132, a=[2,4,9], ans=22999
//n=21132, a=[2,4,9], ans=9999
//n=24132, a=[2,4,9], ans=22999
//n=24132, a=[1,4,9], ans=19999
//n=14132, a=[2,4,9], ans=9999
//n=14132, a=[1,4,9], ans=14119
//n=778, a=[1,4,7], ans=777
//n=777, a=[1,4,7], ans=774
2. LRU cache
注意使用虚拟节点,边界就会好处理很多。
class LRUCache {
public class ListNode {
var val: Int
// 这里记录下key,方便删除最后一个元素
var key = 0
var next: ListNode?
var pre: ListNode?
init(_ val: Int, _ next: ListNode?, _ pre: ListNode?) {
self.val = val
self.next = next
self.pre = pre
}
convenience init(_ val: Int) {
self.init(val, nil, nil)
}
}
let capacity: Int
var map = [Int: ListNode]()
let dummyHead = ListNode(0)
var dummyLast = ListNode(0)
var count = 0
init(_ capacity: Int) {
self.capacity = capacity
dummyHead.next = dummyLast
dummyLast.pre = dummyHead
}
func get(_ key: Int) -> Int {
if let node = map[key] {
// 删除链表节点
deleteNodeInNodeList(node)
// 插入链表头部
insertNodeToHead(node)
return node.val
}
return -1
}
func put(_ key: Int, _ value: Int) {
if let node = map[key] {
node.val = value
// 删除链表节点
deleteNodeInNodeList(node)
// 插入链表头部
insertNodeToHead(node)
} else {
let node = ListNode(value)
node.key = key
map[key] = node
// 插入链表头部
insertNodeToHead(node)
// 判断移除超界限元素
if count == capacity, let last = dummyLast.pre {
// 删除链表节点
deleteNodeInNodeList(last)
map.removeValue(forKey: last.key)
} else {
count += 1
}
}
}
func deleteNodeInNodeList(_ node: ListNode) {
node.pre?.next = node.next
node.next?.pre = node.pre
node.next = nil
node.pre = nil
}
func insertNodeToHead(_ node: ListNode) {
node.next = dummyHead.next
dummyHead.next?.pre = node
dummyHead.next = node
node.pre = dummyHead
}
}
// 持续补充