JavaScript题解 | #24点运算#

24点运算

https://www.nowcoder.com/practice/7e124483271e4c979a82eb2956544f9d

const rl = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.on("line", (line) => {
  judge24Point(line.split(" "));
});

function judge24Point(nums) {
  if (nums.includes("joker") || nums.includes("JOKER")) {
    console.log("ERROR");
    return;
  }
  const numsMap = {
    J: 11,
    Q: 12,
    K: 13,
    A: 1,
  };
  const temp = ["J", "Q", "K", "A"];
  let arr = [];
  nums.forEach((v) => {
    if (temp.includes(v)) {
      arr.push(numsMap[v]);
    } else {
      arr.push(parseInt(v));
    }
  });
  let res = game24(arr);
  if (!res) {
    console.log("NONE");
  }
}
// records 是用来装表达式的【4 + 2 * 13 + 1】
// used(visited) 是回溯里面必备的状态哨兵(标记已经访问了),用来回溯状态的
// 其余参数根据个人情况而定,用到啥写啥
function game24(nums, total = 0, records = [], used = []) {
  // 终止条件
  if (records.length == 7) {
	// dfs找到结果了,输出对应的一条结果
    if (total == 24) {
      let res = "";
      for (let i = 0; i < 7; i++) {
        const temp = records[i];
        if (["+", "-", "*", "/"].includes(temp)) {
          res += temp;
        } else {
          if (temp > 1 && temp < 11) {
            res += temp;
          } else {
            const numMap = {
              1: "A",
              11: "J",
              12: "Q",
              13: "K",
            };
            res += numMap[temp];
          }
        }
      }
      console.log(res);
      return true;
    }
    return false;
  }

  const numsLen = nums.length;
  for (let i = 0; i < numsLen; i++) {
    if (!used.includes(i)) {
      const a = nums[i];
      if (records.length == 0) {
        used.push(i);
        if (game24(nums, a, [a], used)) return true;
        if (game24(nums, a, [a], used)) return true;
        if (game24(nums, a, [a], used)) return true;
        if (game24(nums, a, [a], used)) return true;
        used.pop();
      } else {
		// 标准的回溯模板
		// 1. 对标记做处理
        used.push(i);
		// 2. 递归
        if (game24(nums, total + a, records.concat(["+", a]), used)) return true;
		// 3. 回溯状态
        used.pop();

        used.push(i);
        if (game24(nums, total - a, records.concat(["-", a]), used)) return true;
        used.pop();

        used.push(i);
        if (game24(nums, total * a, records.concat(["*", a]), used)) return true;
        used.pop();

        used.push(i);
		// 这里还是按照题目要求的向下取整比较好,(total / a) >>> 0
        if (game24(nums, total / a, records.concat(["/", a]), used)) return true;
        used.pop();
      }
    }
  }
}

难度:⭐⭐⭐⭐

差一星,在于给的测试用例不够正确,测例3如果使用(total / a)>>> 0自测是判error的,不过我试了最终判断是没问题的。

难点:

这道题和之前有道中等难度的24点很像,思路很像,但是这道题个人觉得更难一点。

1、 这道题计算顺序从左至右,不能包含括号

2、起始递归条件那里很不容易想到要dfs四次,一开始只写了一次,debug到最后发现一直都是4开头(用的测试用例3),后面的牌都遍历了,唯独第一张牌不变。这才想到该如何打乱第一张牌的顺序,那要不直接dfs四次得了。

3、难点3在于,一入递归深似海,再加上回溯条件搞不清楚。

目前做这种回溯的题还是有些迷迷糊糊,还是多做几道,仔细品,仔细品,仔细品。

全部评论

相关推荐

jack_miller:杜:你不用我那你就用我的美赞臣
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务