题目描述:
这天小明正在学数数。他突然发现有些正整数的形状像一座“山”,比如 123565321 、 145541 ,它们左右对称(回文)且数位上的数字先单调不减,后单调不增。小明数了很久也没有数完,他想让你告诉他在区间[2022,2022222022]中有多少个数的形状像一座“山”。
代码实现:
思路见代码解析
方法1:
暴力查找,先判断是否是回文数字,再判断是否是单调不减,大概要花个一分多钟就可以出结果了
package Lq_算法练习;
public class Demo_山 {
public static void main(String[] args) {
int res = 0;
for (int i = 2022; i < 2022222022; i++) {
if (isSum(i) && isHuiwen(i)) {
res++;
}
}
System.out.println(res);
}
// 判断是否是回文数
public static boolean isHuiwen(int num) {
String n1 = "" + num;
// StringBuilder 就相当于C++的String,只是StringBuilder中长度可变,可以通过append 和 insert
// 向其中添加字符串元素
StringBuilder s = new StringBuilder(n1);
/*
* reverse用于字符串反转; toString是一种用于把对象转换为字符串表示形式的方法,可以使用tostring方法来把对象转换为字符串;
* equals用来判断两个字符串是否相等
*/
return s.reverse().toString().equals(n1);
}
// 判断递增不减
public static boolean isSum(int num) {
char[] ch = ("" + num).toCharArray();
int len = ch.length;
/*
* &:按位与。两个位都为1时,结果才为1 len >> 1:len转化为二进制,向右移动1位,最左边补符号位,正数则补0,复数则补1
*/
int mid = (len & 1) == 0 ? len >> 1 : (len >> 1) + 1;// 利用&来进行相于运算,如果结果等于0,则mid=len>>1,否则为后者
for (int i = 0; i < mid - 1; i++) {
if (ch[i] > ch[i + 1]) {// 这里是比较左右两边对称的是否相等,不相等则返回false
return false;
}
}
return true;
}
}
方法2:
同第一种一样也是转化成字符串求解,不过只翻转一半
package Lq_算法练习;
public class Demo_山01 {
public static void main(String[] args) {
int res=0;
for(int i=2022;i<2022222022;i++) {
if(isReturn(i)) {
res++;
}
}
System.out.println(res);
}
public static boolean isReturn(int num) {
//toCharArray()时将字符串对象中的字符转换为一个字符数组
char[] ch=(""+num).toCharArray();
int start=0;
int end=ch.length-1;
while(start<end) {
//如果第一个元素不等于第二个元素,或者第一个元素大于后面一个元素时,该数字一定不是回文数字
if(ch[start]!=ch[end]||ch[start]>ch[start+1]) {
return false;
}
start++;
end--;
}
return true;
}
}
运行结果: