简单的变换题解
30分解法
n范围只有1e6,可以用时间复杂度o(n)的做法,比如递推打表等等,时间复杂度o(n),空间复杂度o(n)。
100分解法
其实不难发现直接模拟本过程即可,时间复杂度即为o(logn),因为每到奇数就会一次操作到偶数,每到偶数就能使n指数级下降,所以时间复杂度o(logn),唯一比较麻烦的地方就是无限循环的,这样直接模拟无疑会TLE。这里提供两种处理的方法:
1.走到必定会死循环的点自动终止
由于每次都只能到达n-3或者n-2这两个点,所以可以得出一个结论,n必然会到达n=1,n=2,n=3三种情况之一,其中n=1,n=2是必定死循环的,递归到这里直接break返回-1即可,递归到n=3只要返回递归次数+1即可(因为从n=3到n=0还需要一步操作)。时间复杂度o(logn),空间复杂度o(logn)(递归logn次系统分配logn大小空间),代码如下:
int ans=0;
void dfs(long long x)
{
ans++;
if(x<3)ans=-1;
else if(x==3);
else
{
if(x%2)dfs(x-3);
else dfs(x/2);
}
}
class Solution {
public:
/**
*
* @param n long长整型
* @return int整型
*/
int Numberofoperations(long long n) {
// write code here
dfs(n);
return ans;
}
};相同逻辑,补充一下验题人给出的非递归做法,走到负数就一定死循环跳出,逻辑和上面的做法几乎完全一致:
class Solution {
public:
/**
*
* @param n long长整型
* @return int整型
*/
int Numberofoperations(long long n) {
// write code here
for(int cnt=0;n>=0;cnt++)
if(!n)
return cnt;
else if(n&1)
n-=3;
else
n/=2;
return -1;
}
};
2.走到一定数量还没有跳出递归则强制跳出递归并输出-1
由于前面对时间复杂度的分析,递归次数最多2*logn次, 所以递归次数超过2*logn,即说明陷入死循环了,直接跳出递归输出-1即可。时间复杂度o(logn),空间复杂度o(logn)(递归logn次系统分配logn大小空间),代码如下:
int ans=0;
void dfs(long long x)
{
if(x==0)return ;
ans++;
if(ans>200)return ;
if(x%2)dfs(x-3);
else dfs(x/2);
}
class Solution {
public:
/**
*
* @param n long长整型
* @return int整型
*/
int Numberofoperations(long long n) {
// write code here
dfs(n);
if(ans<200)
return ans;
else
{
ans=-1;
return ans;
}
}
};
京东工作强度 418人发布