leetcode原题: 24 点游戏(679题)

题目出处: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;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值