最大交换
本题的关键是越往后找到一个最大的数与越靠前的最小的数进行交换。从右往前遍历,找到右边最大数的位置,和左边最小数的位置进行交换
时间复杂度为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 }
等风起的那一天,我已准备好一切