今天1024,程序猿节。本来在图书馆背单词的博主听着旁边可能是在讨论问题的情侣实在是静不下心来。奈何前段时间还丢了耳机。但幸好带了电脑加之听说有1024勋章,便决定总结下之前做过的两道题。虽然题比较简单,但是再简单的题目也有它值得深究的地方。
0:
题目描述:
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
示例 2:输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-number
解题思路:
博主拿到此题的第一反应是将输入的int型数字通过while循环计算出每一位同时将放入字符串中,然后对字符串进行判断。
需要注意的问题:
- 负数直接返回false,int型最长为10位因此在定义字符数组时10位即可。
- 如何优化对字符串的判断? 我的解决办法是利用if循环判断对应位置字符串如不相等直接返回false。
- 如何确定字符串对应位置? 如下图,在计算整形的每一位时记录下总共为几位数字,利用for循环判断时循环初值为0,跳出条件为i<count/2,第i位对应的则为第count-1-i位。
我的答案:
bool isPalindrome(int x){
char str[10];
int i = 0;
if(x<0)
return false;
while(x)
{
str[i] = x%10;
x = x/10;
i++;
}
for(int j=0;j<i/2;j++)
if(str[j]!=str[i-1-j])
return false;
return true;
}
另一种思路答案(出自“一只炸鸡”):
bool isPalindrome(int x){
if (x < 0) return false;
int n = x;
long m = 0;
while (n) {
m *= 10;
m += n % 10;
n /= 10;
}
return m == x;
}
该解法核心思想为利用while循环计算每一位的同时恢复他的逆序结果,然后判断逆序和正序值是否相等。这个答案给我的第一反应是不用开辟字符数组内存消耗可能会少一点,但由于while循环内操作较复杂执行耗时会较长。实际运行结果,两种答案内存消耗相同,第一种解法比第二种快4ms。此处博主也没有弄清楚具体原因,还望在评论区指点。
1:
题目描述:
你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。
给定一个数字 n,找出可形成完整阶梯行的总行数。
n 是一个非负整数,并且在32位有符号整型的范围内。
示例 1:
n = 5
硬币可排列成以下几行:
¤
¤ ¤
¤ ¤因为第三行不完整,所以返回2.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/arranging-coins
解题思路:
拿到这道题目第一想法是循环,给定初值i=1;进行while循环,循环体执行n-=i;i++,如果n-后n仍>=0则证明放满了改行,count++。循环跳出条件设置为n>0。
我的答案:
int arrangeCoins(int n){
int count = 0;
int i=1;
while(n>0)
{
n = n-i;
if(n>=0)
count++;
i++;
}
return count;
}
大佬的骚操作(出自homesway):
int arrangeCoins(int n){
return sqrt((long)2*n+0.25)-0.5;
}
该答案运行耗时击败%100c提交者。对于该问题我们可以建立方程,其中k为行数,n为硬币数目。这样我们便可直接对方程进行求解,从而得出答案。
这种方法需要注意两点:
- 解方程时2*n可能会导致溢出,因此此处需用long int型。
- 对解方程的结果进行取整。
一些感想:
看了上述解法后,博主感觉有一个扎实的数学功底还是很有帮助的。博主再未看评论前根本没有想过列出方程求解,只是一味的考虑如何优化代码从而节省时间复杂度。
最后,祝各位1024快乐。
博主水平有限,行文及代码中不免出现问题,请各位雅正!