每日刷题(一)——下一个回文数

前言

博主最近抖音三面挂在了算法题。复盘时发现是由于遇到陌生的难题,太过紧张,加上以前刷题都是闷着脑袋刷,思路理不清晰,说出思路后,代码编写逻辑也比较混乱。

痛定思痛! 特开每日一题栏目,做每道题时,首先陈述思路,再给出解题代码!

Question

下一个回文数

给定一个数字,返回这个数字的下一个回文数字,以下是几个测试用例:

1 -> 2
121 -> 131
210 -> 212
2233 -> 2332
3322 -> 3333
999 -> 1001
9999 -> 10001

Solution

拿到题目,可以首先可以想到最暴力的解法,即在原数的基础上,不断的+1,然后逐个判断是否是回文数,但是在数字较大的情况下,时间复杂度较高。

比较好一点的解法为,首先将此数字一分为二,将前半段的数字翻转,得到翻转后的数字,随后将前半段数字和翻转后的数字进行拼接,得到result,将此result与原数比较,如果大于原数,就直接返回,如果小于或者等于原数,就将前半段的数字加1后再次进行翻转操作,得到最后的result。

Code

package main

import (
	"fmt"
	"strconv"
)

func GetNextNum(num int) int {
    
    
	var result int
	var flag bool
	//翻转,如果是奇数个数字,需要将最后一位删掉再翻转
	var reverse func(s string, flag bool) string = func(s string, flag bool) string {
    
    
		if flag {
    
    

		} else {
    
    
			s = s[:len(s)-1]
		}
		sbytes := []byte(s)
		for i := 0; i < len(s)/2; i++ {
    
    
			sbytes[i], sbytes[len(s)-i-1] = sbytes[len(s)-i-1], sbytes[i]
		}
		return string(sbytes)
	}

	if num < 9 {
    
    
		return num + 1
	}

	if num == 9 {
    
    
		return 11
	}

	//得到前半段数字
	snum := strconv.Itoa(num)
	allnum := len(snum) + 1 //如果有进位时,特判
	if len(snum)%2 == 0 {
    
    
		flag = true
		snum = snum[:len(snum)/2]
	} else {
    
    
		flag = false
		snum = snum[:len(snum)/2+1]
	}

	//翻转
	afternum := reverse(snum, flag)
	//拼接
	result, _ = strconv.Atoi(snum + afternum)
	//比较大小
	//如果大于 直接返回
	if result > num {
    
    
		return result
	}

	//如果小于
	//前半段数字+1
	prenum, _ := strconv.Atoi(snum)
	prenum++
	tempnum := strconv.Itoa(prenum)
	if len(tempnum) != len(snum) {
    
    
		//产生了进位
		resultnum := ""
		for i := 0; i < allnum; i++ {
    
    
			if i == 0 || i == allnum-1 {
    
    
				resultnum += "1"
			} else {
    
    
				resultnum += "0"
			}
		}
		result, _ = strconv.Atoi(resultnum)
		return result
	} else {
    
    
		snum = tempnum
	}
	//翻转
	afternum = reverse(snum, flag)
	//拼接
	result, _ = strconv.Atoi(snum + afternum)
	return result
	//返回
}

func main() {
    
    
	fmt.Println(GetNextNum(1))
	fmt.Println(GetNextNum(121))
	fmt.Println(GetNextNum(210))
	fmt.Println(GetNextNum(2233))
	fmt.Println(GetNextNum(999))
	fmt.Println(GetNextNum(9999))
}

总结

拿到题目时,一定要先理清思路,随后选择合适的数据结构来解题,而不是盲目的开始做。比如此题的回文数判断等操作,如果使用int类型去做的话,可以做,但是非常繁琐,容易出错,而换成字符串类型,就可以非常简单的进行翻转、判断等。

猜你喜欢

转载自blog.csdn.net/doreen211/article/details/129171703