腾讯笔试题 a,b->A,B
基本思路:因为a,b变到A,B是经过同样的操作。故将a->A的所有操作路径记录下来,从最短的操作路径开始,采用同样的操作匹配b->B,如果匹配,返回最短的操作,如果所有的路径都无法匹配,返回-1。
这样,问题就转化为求小a经过若干的 +1 或者 *2 操作,变为给定的大A问题。此问题的基本思路是采用构造路径二叉树的方法,对于任意数字 n,其操作只有两种 +1 和 *2。我们从a开始,构造其左孩子为 a+1, 右孩子为 a*2,并将其放入队列。每次从队列取出一个结点,如果改结点的值为A,则存入结果路径数组;若该值小于A,则重复上述操作,构造其左右孩子结点并放入队列;若该结点的值大于A,什么也不做。当队列空的时候,所有的路径查找结束,从a到A的所有操作路径都已经在结果路径向量里了。
测试用例:a=3 -> A=12;
输出结果:(此结果路径为逆序路径,1表示\*2,0表示+1)
1 1 (3*2*2)
1 0 0 0 ((3 +1+1+1)*2)
0 0 1 0 0 ((3+1+1)*2+1+1)
0 0 0 0 1 0((3+1)*2+1+1+1+1)
0 0 0 0 0 0 1 (3*2+1+1+1+1+1+1)
0 0 0 0 0 0 0 0 0
#include <iostream>
#include <vector>
#include <deque>
using namespace std;
struct Node
{
int path = 0;//记录路径 0表示加一 1表示乘以2
Node *parent = nullptr; //父节点指针
Node *left = nullptr;
Node *right = nullptr;
double value = 0;
};
int main()
{
int a=3;
int A = 12;
vector<Node*> PATH; //PATH为结果路径 存放A结点的指针
Node *root = new Node;
root->path = -1;
root->value = a;
deque<Node*> mque;
mque.push_back(root);
while (!mque.empty())
{
//弹出队首
Node*p = mque.front();
mque.pop_front();
if (p->value < A) //如果该节点的值小于A,构造其孩子结点
{
//构建两个子孩子
Node *left = new Node;
left->value = p->value + 1;
left->parent = p;
left->path = 0;
Node *right = new Node;
right->value = p->value * 2;
right->parent = p;
right->path = 1;
p->left = left;
p->right = right;
//加入队列
mque.push_back(left);
mque.push_back(right);
}
else if (p->value == A)//如果该节点的值就是A 将其存入结果向量
{
PATH.push_back(p);
}
}
for (int i = 0; i < PATH.size(); i++)
{
Node*p = PATH[i];
while (p != root)
{
cout << p->path << " "; //输出路径 note:此路径为逆序路径
p = p->parent;
}
cout << endl;
}
return 0;
}
阿里云工作强度 619人发布