1. Given an integer, 看这个integer是否是对称的(palindrome), 就是正着和倒着是否都一样
这个有点意思, 时间复杂度O(n)(n 是integer的位数), 这个是必须的, 但是最好的方法必须是要让空间复杂度变成O(1).
分析得仔细点就发现我上面分析的错误, 如果从十位数的位数n这个方面分析, 我们可以发现while loop是O(n)的, 但是里面的 乘法,除法运算都也是O(n)的, 所以总的时间复杂度是O(n^2)的.
至于空间复杂度, 我们再从十进制的位数上来分析, 那么也是O(n)的.
(另外这个问题我是从MITBBS上看来的一道面试题, 发帖的人给出了一个方法是把十进制的每一位放在一个array里面, 然后用stack把逆位储存在另一个array当中, 这个如果换了我当然觉得是我现在的方法空间复杂度更加简便, 但是如果从另一个层面想, 十进制的int本身(每一位)不也是相当于放在一个array当中, 只是它是由编码的bit pattern而确定值, 我这种方法只是针对十进制的int类型做得优化, 但是相对而言之前那个方法反而更加general一些, 写这些只是感觉分析程序优缺点什么的可以想得更general的情况是怎么样, 也许看上去很烂的程序也有自己的好处, 就像最坏情况是O(n^2)的QuickSort竟然在实际中会比一直都是O(nlogn)的HeapSort快一样)
感谢舒晓大神给出的指正!
继续改正, 对于用array的方法, 把所有的的位数, 放在一个array中, 然后用前后两个指针一个向后,一个向前,就是判断string是否是panlidrome的方法.
另外 如果用下面的方法, 有可能出现的问题就是有可能reverse 之后的integer会overflow, 这个问题的解决方法, 当然可以是用long long 来承接reverse之后的integer, 但是这样就显得太不general了, 我也想起了atoi函数里面当时想到的一个问题, 如果overflow了怎么办?(继续延伸, 我想到有次看到讨论如何判断int的乘法是否overflow了, 有个简单的方法是把乘法得出的结果处以任何一个乘数, 看结果是不是另一个乘数)
这个是大官人指出的可能出现的一个问题, 感谢大官人!
int IsPalindrome(int m)
{
int s = 0, temp = m;
while(temp)
{
s = s*10 + temp%10;
temp = temp/10;
}
return s==m;
}
2. Array of non-negative integers. One number appears odd number of times, all the others appear even number of times. Find the number that appears odd number of times.
看到这个题目, 立刻想到了神奇的异或(exclusive or)
int FindOddnumber(int *a, int n)
{
int s = 0;
for(int i=0; i<n; i++)
s ^= a[i];
return s;
}
如果继续问, 不能异或呢, 那么可以考虑Hashtable, 然后进一步或者Hashmap.
Q:
Difference between HashMap and HashTable?
A: The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls. (HashMap allows null values as key and value whereas Hashtable doesnt allow). HashMap does not guarantee that the order of the map will remain constant over time. HashMap is unsynchronized and Hashtable is synchronized.
3. Difference between override and overload
他们都是Polymorphism的一种, one name, many forms,
overload 是compile-time 的(base class, derived class)
override 是run-time 的
4. 找出一个数组中第K小的数(假设这个数组没有重复)
这个主要思路是用quicksort里面的partition函数, 如果return值 order,
order = partition(int *a, int n) 那么代表a[order]是整个数组a当中的第order+1小的数字
if order+1 < K, order = partition(a+order+1, n-order-1), 然后更新 K= K-order-1; if order+1 >K, 继续用order = partition(a, order)
if order+1 = K, bingo, 返回a[order]就好了
时间复杂度是O(n), 最坏情况O(n^2), 然后有个5个点,5个点的,排列的算法, 最坏也有O(n)(不过太麻烦..)
然后如果要求数列的前K小的数, 也可以用类似这种方法, 或者还能想到的就是维持一个Max-Heap, O(nlogK)的复杂度
5. 实现 KMP 算法