一.方法介绍
- 若面试时是关于n位的整数并且没有限定n的取值范围,或者说输入是一个任意大小的数字,则说明很可能要考虑大数问题,也即可能超出存储范围,这时可以换long long存储或者转为用字符串来表示。
- int型的最大值是0x7fffffff,最小值是0x8000000
- 若在计算和的时候超过int型,比如A+B+C+D==target的判定,可以把和的形式改成A+B==target-C-D的判定。
二.leetcode题
7.整数反转
题目链接
无论是正数还是负数,都可以用正常手段求解。
在求解过程中,一旦结果已经超过int型的最大值和最小值,则直接返回结束。
int型的最大值是0x7fffffff,最小值是0x8000000
9.回文数
- 不申请额外的空间,只取出数字的一半进行反转,然后对比,比如1221,取出21反转12和12比较,
- 如何判断已经取了一半数字了:就是当取出的反转数revertNum大于等于剩下的数x时,则说明已经对半,
- 判断长度奇数偶数情况:如果是偶数的话,则revertNum是和x相等;若是奇数,则最中间的数字在revertNum的最低位上,将它除以10以后要和x相等, 所以得到 return x==revertNum || x==revertNum/10;
55.跳跃游戏-(最远距离)
题目链接
题目并没有说要把这个跳法给找出来,而是问能不能跳,因此,不需要纠结究竟是从哪开始起跳,起跳路径是什么,只需要知道能跳的最远距离能不能到达尾部即可。
解法:挨个跳,
1.依次遍历,把每个点都作为起跳点去尝试,然后更新能跳到的最远的位置maxh
2.跳不成功的退出条件: 能跳到的最远的位置maxh比当前遍历到的点的下标的位置还要小,说明没法到达了
3.对于能跳到的最远位置maxh,说明这个位置往左的所有位置都是可达的,都是可以依次遍历的
bool canJump(vector<int>& nums) {int maxh=0,i,j;for (i=0;i<nums.size();i++) {if (maxh<i)return false;maxh=((i+nums[i])>maxh) ? (i+nums[i]) : maxh;}return true;}
168.Excel表列名称-(进制转换,余数除数)
题目链接
这里是将十进制转换成2位的26进制数,不过有一点要注意的是,这里映射的是1-26,而不是0-25,因此,需要在模的时候(x-1)%d, 人为将余数转换到0-25,再进行映射。
169.多数元素-(投票算法)-人多势众
题目链接
解法: 投票选举法 ,大于n/2
candidate是候选众数,count是候选众数出现的次数
如果count==0,则对candidate=nums[i],并且判断
则若candidate==nums[i],就count++;
若candidate!=nums[i],就count—;
最后投票选举出来的candidate就是众数。
也即若候选人不是众数,则众数会和其他数一起反对,即候选人一定会下台;若候选人是众数,则由于众数的数目是超过一半的,则众数一定会当选。
不妨假设整个数组的众数记做a,则最初的数组中a的数量大于其余所有数。当采用count计数的时候有两种情况: 1)假设candidate等于a,则当count从1变为0的过程,此区间内a的数量等于其余数的数量,因此以count=0为分界线,数组右端部分的众数仍然为a
2)假设candidate不等于a,则当count从1变为0的过程, 此区间内a的数量小于等于其余数的数量,因此以count=0为分界线,数组右端部分的众数仍然为a
172.阶乘后的零-(阶乘判0)
题目链接
每个尾部的0由2x5=10得到,因此,阶乘数里总共有多少对(2,5),就是有多个0。
又由于质因子2的数量是远多于质因子5的数量的,因此,可以只统计阶乘结果里有多少个质因子5。与此同时,由于是阶乘,因此不需要真正将结果计算出来。
如何计算阶乘里面有多少个5?
25/5=5是有5个5相加,然后把5个5变成5个1,即为5,5/5=1,表示有1个5相加,
100/5=20表示有20个5相加,然后变成20个1相加,20/5=4表示有4个5相加,然后相当于4个1相加。
因此,有了下面的递归公式的代码
int trailingZeroes(int n) {
return n == 0? 0: n / 5 + trailingZeroes(n / 5);
}
204.计数质数-(埃氏筛统计质数)
题目链接
埃氏筛—厄拉多塞筛法基本思想:
若x是质数,则大于x的x的倍数2x, 3x,…一定不是质数
设isPrimes[i]表示数i是否是质数,若质数则为true,否则为false。
同时可以继续优化,可以不用从2x开始标记,可以直接从xx进行标记,因为显然,2x等在x之前的倍数已经被标记过了,从xx标记到x*j
代码细节注意:
这里有一点要注意的是,由于xx可能会超过int的存储,因此不建议用for (j=x;jx
if((long)xx
326.3的幂
题目链接
一种是利用对数, ,则若n是3的整数次方,则m一定是整数.
另一种是比较取巧的,如在int型范围内3的最大次方是=1162261467,则若n是3的整数次方,则1162261467除以n的余数一定是零。
剑指Offer面试题17:打印从1到最大的n位数
题目:
输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数999。
这道题不能直接以整形进行按顺序输出打印,因为没有规定n的大小,因此,有可能会超出int型甚至是长整型(long long int),也即我们需要考虑大数问题。
因此,这道题要利用字符串进行加1操作。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string AddOne(string num) {
reverse(num.begin(), num.end());
int index = 1, i = 0, seat;
for (i = 0; i < num.size() && index != 0; i++) {
seat = (num[i] - '0' + index)%10;
index = ((num[i] - '0') + index)/10;
num[i] = '0' + seat;
}
if (index == 1)
num.push_back('1');
reverse(num.begin(), num.end());
return num;
}
int main() {
string num = "1";
int n = 2;
if (n<=0)
cout<<"InputError!";
for (; num.size() <= n;) {
cout << num << endl;
num = AddOne(num);
}
return 0;
}
258.各位相加
题目链接
50.Pow(x,n)
- 以成倍的形式进行计算,快速幂法+递归
- 由于是double,因此在判等时,不能是1e-8而是1e-10
double Helper(long long int N,double x){ if (N==1) return x; double y=Helper(N/2,x); return (N%2==0)? y*y:y*y*x; } double myPow(double x, int n) { long long int N=n; if (n==0||abs(x-1.00)<=1e-10) return 1.0; x=(n<0)? (1/x):x; N=(n<0)? -N:N; return Helper(N,x); }
