最大交换
本题的关键是越往后找到一个最大的数与越靠前的最小的数进行交换。从右往前遍历,找到右边最大数的位置,和左边最小数的位置进行交换
时间复杂度为O(len(num))
func maximumSwap(num int) int { numStr := fmt.Sprintf("%d", num) if len(numStr) == 1 { return num } leftMin := -1 rightMax := 0 // 从右往前遍历,找到右边最大数的位置,和左边最小数的位置进行交换 maxIndex := len(numStr) - 1 for i := len(numStr) - 2; i >= 0; i-- { //倒数第二个往前遍历 //左边值比当前值大,更新最大索引 if numStr[i] > numStr[maxIndex] { maxIndex = i } else if numStr[i] < numStr[maxIndex] { //值相等情况,优先取靠右的,因为这样子高位损失最小 //左边值比当前值小,分别记录左边最小,右边最大 leftMin = i rightMax = maxIndex } } if leftMin == -1 { // 这意味着 numStr 是降序的,不需要交换 return num } byt := []byte(numStr) tmp := byt[leftMin] byt[leftMin] = byt[rightMax] byt[rightMax] = tmp ans, _ := strconv.Atoi(string(byt)) return ans }
变种,如果要求至少交换一次,要求输出最大值
思路:如果最后发现没有可行的交换,说明整个数据是倒序的,交换最后末尾两个就可以了
func maximumSwap(num int) int { numStr := fmt.Sprintf("%d", num) if len(numStr) == 1 { return num } leftMin := -1 rightMax := 0 // 从右往前遍历,找到右边最大数的位置,和左边最小数的位置进行交换 maxIndex := len(numStr) - 1 for i := len(numStr) - 2; i >= 0; i-- { //倒数第二个往前遍历 //左边值比当前值大,更新最大索引 if numStr[i] > numStr[maxIndex] { maxIndex = i } else if numStr[i] < numStr[maxIndex] { //值相等情况,优先取靠右的,因为这样子高位损失最小 //左边值比当前值小,分别记录左边最小,右边最大 leftMin = i rightMax = maxIndex } } if leftMin == -1 { // 这意味着 numStr 是降序的 return swapAnd2Int([]byte(numStr), 0, 1) } return swapAnd2Int([]byte(numStr), leftMin, rightMax) } func swapAnd2Int(byt []byte, a, b int) int { tmp := byt[a] byt[a] = byt[b] byt[b] = tmp ans, _ := strconv.Atoi(string(byt)) return ans }
等风起的那一天,我已准备好一切
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架