目录
初始算法:
class Solution {
public:
bool isPalindrome(int x){
if(x < 0)
{
return false;
}
else if(x == 0)
{
return true;
}
int array[100] = {-1},arra[100] = {-1};
int i = 0,result = 0;
for(i = 0;x != 0;i++)
{
array[i] = x % 10;
x = x / 10;
}
printf("i = %d",i);
for(int n = 0;n < i;n++)
{
arra[n] = array[i - 1 - n];
}
int n = 0;
for(n = 0;n < i;n++)
{
if(arra[n] != array[n])
{
break;
}
}
if(n == i)
{
return true;
}
else
{
return false;
}
}
};
- 首先,如果输入的整数
x
小于0,那么它肯定不是回文数,直接返回false
。 - 如果
x
等于0,那么它是回文数,直接返回true
。 - 创建一个大小为100的整数数组
array
和arra
,并初始化为-1。这两个数组用于存储整数x
的每一位数字。 - 通过一个循环,将
x
的每一位数字存储到array
数组中。 - 然后,通过另一个循环,将
array
数组中的数字反转存储到arra
数组中。 - 最后,通过比较
array
和arra
数组中的每一位数字,如果有任何一位数字不相同,那么x
就不是回文数,返回false
。如果所有位都相同,那么x
就是回文数,返回true
。
时间复杂度:
-
首先,原算法中第一个
for
循环用于将整数x
的每一位数字提取出来并存储到array
数组中。这个循环会执行log10(x)
次(假设x
是正整数),因为每次迭代都将x
除以10。因此,这个循环的时间复杂度是O(log10(x))。 -
接下来,原算法中第二个
for
循环用于将array
数组中的数字反转并存储到arra
数组中。这个循环同样会执行log10(x)
次。因此,这个循环的时间复杂度也是O(log10(x))。 -
最后,原算法中第三个
for
循环用于比较array
和arra
数组中的每一位数字。这个循环同样会执行log10(x)
次。因此,这个循环的时间复杂度也是O(log10(x))。 -
综上,原算法的总时间复杂度是O(log10(x)),因为所有主导时间复杂度的操作都是O(log10(x))。
空间复杂度:
- 原算法中使用了两个大小为100的整数数组
array
和arra
来存储整数x
的每一位数字及其反转。因此,无论x
的大小如何,空间复杂度都是O(1),因为使用的空间是固定的。
改进后:
class Solution {
public:
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
std::vector<int> digits;
while (x > 0) {
digits.push_back(x % 10);
x /= 10;
}
int left = 0, right = digits.size() - 1;
while (left < right) {
if (digits[left] != digits[right]) {
return false;
}
left++;
right--;
}
return true;
}
};
- 输入验证:
- 首先,函数检查输入的整数
x
是否小于0。如果是,则直接返回false
,因为负数不可能是回文数。
- 首先,函数检查输入的整数
- 提取数字位:
- 接下来,函数创建一个空的
std::vector<int>
名为digits
,用于存储x
的每一位数字。 - 使用一个
while
循环,只要x
大于0,就不断执行循环体。在每次循环中,通过取模运算x % 10
得到x
的最后一位数字,并将其添加到digits
向量的末尾。然后,通过整除运算x /= 10
去掉x
的最后一位。 - 当
x
变为0时,循环结束,此时digits
向量中存储了x
的所有位数字,且是按从低位到高位的顺序存储的。
- 接下来,函数创建一个空的
- 比较数字位:
- 初始化两个指针
left
和right
,分别指向digits
向量的第一个元素和最后一个元素。 - 使用一个
while
循环,只要left
小于right
,就不断执行循环体。在每次循环中,比较digits[left]
和digits[right]
是否相等。如果不相等,则说明x
不是回文数,直接返回false
。 - 如果相等,则将
left
指针向右移动一位(即left++
),将right
指针向左移动一位(即right--
),继续比较下一对数字。 - 当
left >= right
时,循环结束。这意味着所有对应的数字位都已经比较过,且都相等。
- 初始化两个指针
- 返回结果:
- 如果上述比较过程中没有发现不匹配的数字位,则函数返回
true
,表示x
是一个回文数。
- 如果上述比较过程中没有发现不匹配的数字位,则函数返回
这个算法的关键在于它使用了双指针法来比较数字位,从而避免了将整个数字反转后再进行比较的需要。这种方法减少了不必要的计算,并使得算法的时间复杂度和空间复杂度都与输入整数x
的位数(即log10(x)
)成正比,而不是与x
的绝对值大小成正比。因此,该算法在处理大整数时非常高效。
时间复杂度:
-
提取数字位的过程(将整数
x
的每一位数字提取出来并存储到digits
向量中)的时间复杂度是O(log10(x)),因为每次迭代都将x
除以10,直到x
变为0。 -
比较数字位的过程(使用双指针法比较
digits
向量的前半部分和后半部分)的时间复杂度也是O(log10(x)),因为指针left
从0开始,指针right
从digits.size() - 1
开始,每次迭代都向中间移动,直到left >= right
。
因此,整个函数的时间复杂度是O(log10(x)) + O(log10(x)) = O(log10(x)),其中主导项是O(log10(x))。
空间复杂度:
digits
向量用于存储整数x
的每一位数字。在最坏的情况下,即x
是一个非常大的整数,digits
的大小可能接近log10(x)
。因此,空间复杂度是O(log10(x))。
综上所述,修正后的isPalindrome
函数具有线性的时间复杂度O(log10(x))和线性的空间复杂度O(log10(x))。这是因为函数执行的操作次数和使用的额外存储空间都与输入整数x
的位数(即log10(x)
)成正比。这种复杂度分析表明,该算法在处理大整数时非常高效,因为它不依赖于整数的绝对值大小。