楼主: 匿名
跳转到指定楼层
上一主题 下一主题
收起左侧

骨骼现场两道

 
🔗
umialpha 2020-12-9 17:36:59 | 只看该作者
全局:
对于第二题,我有个行得通但是很麻烦的方法,复杂度也是O(n).
1. 构建表达式树。
2. 根据表达式树算出最小flips。

贴出一个代码,我已经感觉到部分优化的点了。看看能不能写个更简单的方法。
  1. class ExpressionNode:

  2.     def __init__(self, e, left=None, right=None):
  3.         self.e = e
  4.         self.left, self.right = left, right

  5.     def left_flips(self):  
  6.         return self.left.flips() if self.left else 0

  7.     def right_flips(self):
  8.         return self.right.flips() if self.right else 0

  9.     def left_val(self):
  10.         return self.left.val() if self.left else 0

  11.     def right_val(self):
  12.         return self.right.val() if self.right else 0

  13.     def val(self):
  14.         if self.e == "1" or self.e == "0":
  15.             return int(self.e)
  16.         if self.e == "|":
  17.             return self.left_val() or self.right_val()
  18.         if self.e == "&":
  19.             return self.left_val() and self.right_val()

  20.         raise Exception("invalid expression")

  21.     def flips(self):
  22.         if self.e == "1" or self.e == "0":
  23.             return 1
  24.         if self.e == "|":
  25.             # 1 | 0, 0 | 1  => 1 & 0, 0 & 1
  26.             if self.left_val() != self.right_val():
  27.                 return 1
  28.             # 1 | 1  = > 1 & 0, 0 & 1
  29.             elif self.left_val() == 1:
  30.                 return min(self.left_flips(), self.right_flips()) + 1
  31.             # 0 | 0 => 1 | 0, 0 | 1
  32.             else:
  33.                 return min(self.left_flips(), self.right_flips())
  34.         elif self.e == "&":
  35.             # 1 & 0, 0 & 1 => 1 | 0, 0 | 1
  36.             if self.left_val() != self.right_val():
  37.                 return 1
  38.             # 1 & 1 => 0 & 1, 1 & 0
  39.             elif self.left_val() == 1:
  40.                 return min(self.left_flips(), self.right_flips())
  41.             # 0 & 0 => 0 | 1, 1 | 0
  42.             return min(self.left_flips(), self.right_flips()) + 1
  43.            
  44.         raise Exception("Invalid node")

  45. def convert_to_suffix(exp):

  46.     P = {
  47.         "|": 2,
  48.         "&": 3,
  49.         "(": 1,
  50.     }

  51.     stk = []
  52.     ans = []
  53.     for e in exp:
  54.         if e == "1" or e == "0":
  55.             ans.append(e)
  56.         elif e in ["&", "|"]:
  57.             while stk and P[stk[-1]] > P[e]:
  58.                 ans.append(stk.pop())
  59.             stk.append(e)
  60.         elif e == "(":
  61.             stk.append(e)
  62.         elif e == ")":
  63.             while stk and stk[-1] != "(":
  64.                 ans.append(stk.pop())
  65.             # popout "("
  66.             stk.pop()

  67.     while stk:
  68.         ans.extend(stk.pop())
  69.     return "".join(ans)

  70. def build_tree(suffix_exp):
  71.     stk = []
  72.     for e in suffix_exp:
  73.         if e == "1" or e == "0":
  74.             stk.append(ExpressionNode(e))
  75.         else:
  76.             right = stk.pop()
  77.             left = stk.pop()
  78.             stk.append(ExpressionNode(e, left, right))
  79.    
  80.     return stk[0]

  81. if __name__ == "__main__":
  82.     # e = "1 & (0&(1|1))"
  83.     # print(build_tree(convert_to_suffix(e)).flips())
  84.     testcases = [
  85.         ["1 | 0 & 1", 1],
  86.         ["1 & 0 | 0", 1],
  87.         ["1 | 0 | 0", 1],
  88.         ["1 & (0&(1|1))", 1],
  89.         ["1 | (0&(1|1))", 1],
  90.         ["1 | (1&(1|1))", 2],
  91.     ]
  92.     for inp, out in testcases:
  93.         ans = build_tree(convert_to_suffix(inp)).flips()
  94.         assert(ans == out), (inp, out, ans)
复制代码


回复

使用道具 举报

🔗
umialpha 2020-12-9 22:07:27 | 只看该作者
全局:
稍微简化版的来啦。去掉了构建表达式树这一步骤,不过思路还是一样。
解释几点:
1. 依然后缀表达式,主要是为了去掉括号。
2. class Val 存储了当前sub表达式的value和min flip。
  1. def min_flips(exp):

  2.     # trim whitespace
  3.     exp = "".join([e for e in exp if e != " "])
  4.    
  5.     class Val:
  6.         def __init__(self, v, flip):
  7.             self.v, self.flip = v, flip

  8.         def __str__(self):
  9.             return "Val (%s, %s,)" %(self.v, self.flip)

  10.     def convert_to_suffix(exp):
  11.         P = {
  12.                 "|": 2,
  13.                 "&": 3,
  14.                 "(": 1,
  15.             }
  16.         ans = []
  17.         stk = []
  18.         for e in exp:
  19.             if e == " ":
  20.                 continue
  21.             if e in ["1", "0"]:
  22.                 ans.append(Val(int(e), 1))
  23.             elif e == "(":
  24.                 stk.append(e)
  25.             elif e == ")":
  26.                 while stk and stk[-1] != "(":
  27.                     ans.append(stk.pop())
  28.                 stk.pop()
  29.             else:
  30.                 while stk and P[stk[-1]] >= P[e]:
  31.                     ans.append(stk.pop())
  32.                 stk.append(e)

  33.         ans.extend(stk[::-1])
  34.         return ans

  35.     arr = convert_to_suffix(exp)
  36.     stk = []
  37.     for e in arr:
  38.         if e in ["|", "&"]:
  39.             rv, lv = stk.pop(), stk.pop()
  40.             curv = Val(None, None)
  41.             if e == "|":
  42.                 curv.v = lv.v or rv.v
  43.                 # 1 | 0, 0 | 1 => 1 & 0, 0 & 1
  44.                 if lv.v != rv.v:
  45.                     curv.flip = 1
  46.                 # 0 | 0 => 1 | 0, 0 | 1
  47.                 elif lv.v == 0:
  48.                     curv.flip = min(lv.flip, rv.flip)
  49.                 # 1 | 1 => 1 & 0, 0 & 1
  50.                 elif lv.v == 1:
  51.                     curv.flip = min(lv.flip, rv.flip) + 1
  52.             else:
  53.                 curv.v = lv.v and rv.v
  54.                 # 1 & 0, 0 & 1 => 1 | 0, 0 | 1
  55.                 if lv.v != rv.v:
  56.                     curv.flip = 1
  57.                 # 1 & 1 => 0 & 1, 1 & 0
  58.                 elif lv.v == 1:
  59.                     curv.flip = min(lv.flip, rv.flip)
  60.                 # 0 & 0 => 0 | 1, 1 | 0
  61.                 elif lv.v == 0:
  62.                     curv.flip = min(lv.flip, rv.flip) + 1
  63.             stk.append(curv)
  64.         else:
  65.             stk.append(e)
  66.    
  67.     return stk[-1].flip



  68. # 1 (&1|( 0&0 )|1)|0&(0& (1|1| 0))

  69. if __name__ == "__main__":
  70.     testcases = [
  71.         ["1 | 0 & 1", 1],
  72.         ["1 & 0 | 0", 1],
  73.         ["1 | 0 | 0", 1],
  74.         ["1 & (0&(1|1))", 1],
  75.         ["1 | (0&(1|1))", 1],
  76.         ["1 | (1&(1|1))", 2],
  77.         ["1&(0|1)", 1],
  78.         ["(1 |(1&1|( 0&0 )|1))|0&(0& (1|1| 0))", 1]
  79.     ]
  80.     for inp, out in testcases:
  81.         # ans = build_tree(convert_to_suffix(inp)).flips()
  82.         # assert(ans == out), (inp, out, ans)

  83.         ans2 = min_flips(inp)
  84.         assert(ans2 == out), (inp, out, ans2)
复制代码

评分

参与人数 2大米 +5 收起 理由
showton + 2 欢迎分享你知道的情况,会给更多积分奖励!
wilbur_zzz + 3 很有用的信息!

查看全部评分

回复

使用道具 举报

🔗
dragonway 2020-12-10 03:32:12 | 只看该作者
全局:
您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
回复

使用道具 举报

🔗
flyingforce 2020-12-10 04:15:19 | 只看该作者
全局:
您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
回复

使用道具 举报

🔗
ee19920302 2020-12-12 11:00:10 | 只看该作者
全局:
您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
回复

使用道具 举报

🔗
fiya.noodles 2020-12-23 10:40:37 | 只看该作者
全局:
您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies

评分

参与人数 1大米 +1 收起 理由
johnnywsd + 1 很有用的信息!

查看全部评分

回复

使用道具 举报

🔗
johnnywsd 2020-12-24 08:51:14 | 只看该作者
全局:
您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
回复

使用道具 举报

🔗
lyronly 2020-12-30 14:38:26 | 只看该作者
全局:
本帖最后由 lyronly 于 2020-12-30 15:31 编辑

1 建树
2 遍历树得到eval的值
3 再次遍历树通过 eval的 值 和 当前的符号 | 还是 & 还是 0 1 得到当前node的最小flip值

  1. struct node
  2. {
  3.     char v;
  4.     int r;
  5.     // c == 0 , v is 0 or 1, else c == 2
  6.     int c = 0;
  7.     node* a[2];
  8.     node(char input)
  9.     {
  10.         v = input;
  11.         if (input == '|' || input == '&')
  12.         {
  13.             c = 2;
  14.             a[0] = nullptr;
  15.             a[1] = nullptr;
  16.         }
  17.         else
  18.         {
  19.             c = 0;
  20.         }
  21.     }
  22. };
  23. class Solution {
  24. public:
  25.     string s;
  26.     int n;
  27.     node* getnumber(int& i)
  28.     {
  29.         if (i >= n)
  30.         {
  31.             return nullptr;
  32.         }
  33.         node* n1 = nullptr;
  34.         if (s == '(')
  35.         {
  36.             i++;
  37.             n1 = build(i);
  38.         }
  39.         else if (s == '0' || s == '1')
  40.         {
  41.             n1 = new node(s);
  42.             i++;
  43.         }
  44.         return n1;
  45.     }
  46.     node* build(int& i)
  47.     {
  48.         if (i >= n)
  49.         {
  50.             return nullptr;
  51.         }
  52.         node* n1 = getnumber(i);
  53.         if (i >= n)
  54.         {
  55.             return nullptr;
  56.         }
  57.         node* cur = new node(s);
  58.         i++;
  59.         node* n2 = getnumber(i);
  60.         if (i < n && s == ')')
  61.         {
  62.             i++;
  63.         }
  64.         cur->a[0] = n1;
  65.         cur->a[1] = n2;
  66.         return cur;
  67.     }
  68.     int res = INT_MAX;
  69.     int eval(node* root)
  70.     {
  71.         if (root->c == 0)
  72.         {
  73.             root->r = root->v - '0';
  74.             return root->r;
  75.         }
  76.         int l = eval(root->a[0]);
  77.         int r = eval(root->a[1]);
  78.         root->r = (root->v == '|') ? (l | r) : (l & r);
  79.         return root->r;
  80.     }
  81.     int flip(node* root)
  82.     {
  83.         if (root->c == 0)
  84.         {
  85.             return 1;
  86.         }
  87.         int l = root->a[0]->r;
  88.         int r = root->a[1]->r;
  89.         if (root->v == '|')
  90.         {
  91.             if (root->v == 0)
  92.             {
  93.                 return min(flip(root->a[0]), flip(root->a[1]));
  94.             }
  95.             else
  96.             {
  97.                 // both 1
  98.                 if (l == r)
  99.                 {
  100.                     // change to &
  101.                     return min(flip(root->a[0]), flip(root->a[1])) + 1;
  102.                 }
  103.                 else
  104.                 {
  105.                     return 1;
  106.                 }
  107.             }
  108.         }
  109.         else
  110.         {
  111.             if (root->v == 1)
  112.             {
  113.                 return min(flip(root->a[0]), flip(root->a[1]));
  114.             }
  115.             else // a&b == 0
  116.             {
  117.                 // both 0
  118.                 if (l == r)
  119.                 {
  120.                     return min(flip(root->a[0]), flip(root->a[1])) + 1;
  121.                 }
  122.                 else
  123.                 {
  124.                     return 1;
  125.                 }
  126.             }
  127.         }
  128.     }
  129.     int minflip(string exp)
  130.     {
  131.         n = exp.size();
  132.         s = exp;
  133.         int i = 0;
  134.         node* root = build(i);
  135.         eval(root);
  136.         return flip(root);
  137.     }
  138. };
复制代码
[i][i][i][/i][/i][/i]
回复

使用道具 举报

🔗
mathusic2020 2020-12-30 14:53:20 | 只看该作者
全局:
您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
回复

使用道具 举报

🔗
lyronly 2020-12-30 15:23:42 | 只看该作者
全局:
您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
使用VIP即刻解锁阅读权限或查看其他获取积分的方式
游客,您好!
本帖隐藏的内容需要积分高于 100 才可浏览
您当前积分为 0。
VIP即刻解锁阅读权限查看其他获取积分的方式
Unlock interview details and practice with AI
Curated Interview Questions from Top Companies
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表