题目出处:leetcode
问题所在:运算符优先级、所有可能的运算符和数字的排列
思路:暴力求解
1)、穷举所有的数字组合(leetcode原题中的组合问题)、穷举所有的运算符号排列。
2)、将运算符序列和数字序列按序构建一个中缀表达式的二叉树,这就消除了运算符优先级的影响,也就不需要考虑括号问题了。
3)、问题转化为中缀表达式的求解问题,注意int符号扩展为double类型即可。
思路比较明显,就是过于暴力,当然leetcode上还有人的代码是O(1)时间复杂度的,还是Python代码,我当场惊呆了,hhhhh!
C++代码如下:
// A C++ Solution
class Solution {
public:
class MyTreeNode {
public:
int val;
bool flag=false;//false代表数字,true代表算符
MyTreeNode *left;
MyTreeNode *right;
MyTreeNode(){left=NULL;right=NULL;};
};
vector<vector<int>> res;//使用结果
vector<bool> visited;//用于标记nums数组的访问情况
vector<vector<int>> permute(vector<int>& nums,int num) {
res.clear();
visited.clear();
if (nums.size() == 0)
return res;
visited=vector<bool>(nums.size(),false);
vector<int> current;
help(nums, current,num);
return res;
}
void help(vector<int>&nums, vector<int>& currentResult,int num) {
if (currentResult.size() == num) {
res.push_back(vector<int>(currentResult));
return;
}
for (int a = 0; a < visited.size(); a++) {
if (visited[a] == false) {
visited[a] = true;
currentResult.push_back(nums[a]);
help(nums, currentResult,num);
currentResult.pop_back();
visited[a] = false;
}
}
}
void Constructor(MyTreeNode*root,vector<int>nums,int a,int b,int c,int type){//树的类型有五种
//中缀表达式的四个叶子结点huffman树总共有五种形态。
//赋值,设置树的形态
for(int a=0;a<4;a++)
root[a+3].val=nums[a];
root[0].val=a;
root[1].val=b;
root[2].val=c;
switch (type)
{
case 1:
root[0].left=&root[1]; root[0].right=&root[6]; //中间节点从上到下为012
root[1].left=&root[2]; root[1].right=&root[5]; //叶子结点,从左到右为3456
root[2].left=&root[3]; root[2].right=&root[4];
break;
case 2:
root[0].left=&root[3]; root[0].right=&root[1];
root[1].left=&root[4]; root[1].right=&root[2];
root[2].left=&root[5]; root[2].right=&root[6];
break;
case 3:
root[0].left=&root[1]; root[0].right=&root[2];
root[1].left=&root[3]; root[1].right=&root[4];
root[2].left=&root[5]; root[2].right=&root[6];
break;
case 4:
root[0].left=&root[3]; root[0].right=&root[1];
root[1].left=&root[2]; root[1].right=&root[6];
root[2].left=&root[4]; root[2].right=&root[5];
break;
case 5:
root[0].left=&root[1]; root[0].right=&root[6];
root[1].left=&root[3]; root[1].right=&root[2];
root[2].left=&root[4]; root[2].right=&root[5];
break;
default:
break;
}
}
double execute(MyTreeNode*root){
if(root->flag){
double leftVal=execute(root->left);
double rightVal=execute(root->right);
if(leftVal==-100000||rightVal==-100000)
return -100000;
switch (root->val)
{
case 1:
/* + */
return leftVal+rightVal;
break;
case 2:
/* - */
return leftVal-rightVal;
break;
case 3:
/* * */
return leftVal*rightVal;
break;
case 4:
/* / */
if(rightVal==0)
return -100000;
else
{
return leftVal/rightVal;
}
break;
default:
break;
}
}
return double(root->val);
}
bool judgePoint24(vector<int>& nums) {
MyTreeNode*root=new MyTreeNode[7];//四个叶节点的huffman树有6个节点
for(int a=0;a<3;a++)
root[a].flag=true;
vector<vector<int>> reNum=permute(nums,nums.size());
vector<vector<int>> opNum;
for(int a=1;a<=4;a++){
for(int b=1;b<=4;b++){
for(int c=1;c<=4;c++){
opNum.push_back(vector<int>({a,b,c}));
}
}
}
for(int a=0;a<reNum.size();a++){
for(int b=0;b<opNum.size();b++){
for(int c=1;c<=5;c++){
Constructor(root,reNum[a],opNum[b][0],opNum[b][1],opNum[b][2],c);
double temp=execute(root);
if(abs(temp-double(24))<0.001){
return true;
}
}
}
}
return false;
}
};