问大家一个面试题

2019-09-06 22:56:13 +08:00
 fenghuang

'1(2(3,4(,5)),6(7,))' 把这个字符串转成二叉树

     1
   /   \
  2     6
 / \   / \
3   4 7
     \
      5
5724 次点击
所在节点    程序员
37 条回复
kuanng
2019-09-07 12:51:19 +08:00
function Tree(data) {
this.data = data
this.lchild = null
this.rchild = null
}
function createTree(data) {
data = data.split('')
let stack = []
let flag = -1
while (data.length) {
let val = data.shift()
if (val === '(') {
if (flag === 0) {
stack.push(stack[stack.length - 1].lchild)
} else if (flag === 1) {
stack.push(stack[stack.length - 1].rchild)
}
flag = 0
} else if (val === ')') {
stack.pop()
} else if (val === ',') {
flag = 1
} else {
let node = new Tree(val)
if (flag === -1) {
root = node
stack.push(node)
} else if (flag === 0) {
stack[stack.length - 1].lchild = node
} else {
stack[stack.length - 1].rchild = node
}
}
}
return root
}
kuanng
2019-09-07 12:54:38 +08:00
@kuanng createTree 函数中漏了一行: let root = null
fenghuang
2019-09-07 15:30:33 +08:00
大家都喜欢用 js 做题?
brainfxxk
2019-09-07 16:10:16 +08:00
我咋觉得这是 LeetCode 原题...
stevenkang
2019-09-07 17:31:47 +08:00
这样 OK ?
```js
JSON.parse('{' + ( '1(2(3,4(,5)),6(7,))'.replace(/,\)/g,')').replace(/\(,/g, '(').replace(/\(/g, ':{').replace(/\)/g, '}').replace(/(\d)([,}]{1})/g, '$1:""$2').replace(/(\d)/g, '"$1"') ) + '}')
```
![v2ex1.png]( https://i.loli.net/2019/09/07/cdBSA4xepN7DftZ.png)
niubee1
2019-09-07 18:07:00 +08:00
@unionx 悟空,你又调皮了
ClarkAbe
2019-09-07 20:05:54 +08:00
转换成 json 然后按照 json 方式处理😶
aogu555
2019-09-07 20:07:59 +08:00
字符串本身已经是前序遍历了
jaskle
2019-09-07 20:39:21 +08:00
if(a=='1(2(3,4(,5)),6(7,))'){
1
/ \
2 6
/ \ / \
3 4 7
\
5
}
shuirong1997
2019-09-07 21:37:20 +08:00
@rabbbit 啥编辑器?这么简约
zhengjian
2019-09-07 21:42:00 +08:00
normalize
2019-09-07 21:47:11 +08:00
//12(2(34,4(,5)),6(7,))
//没有测试太多
function treeNode(val) {
this.val = parseInt(val)
this.right = null
this.left = null
}

function stringToTree(str) {
var ary = [] //[1,2,3,4,null,5,6,7]
var re = /\d+/g
re.lastindex = 0
var match

for(var i = 0; i < str.length; i++) {
if(str[i] == ',' && str[i - 1] == '('){
ary.push(null)
}else if(str[i] == ')') {
if(str[i - 1] == ',') {
ary.push(null)
}

var preNode = ary.slice(-3)
ary = ary.slice(0, -3)

preNode[0].left = preNode[1]
preNode[0].right = preNode[2]
ary.push(preNode[0])

}else if(str[i] == '('){
continue
}else if(match = re.exec(str)) {
ary.push(new treeNode(match[0]))
i = match.index + match[0].length - 1
}
}

return ary[0]
}
jedihy
2019-09-08 03:14:24 +08:00
不知道有没有 bug

leafdream
2019-09-08 11:03:30 +08:00
#11 的思路

vincenttone
2019-09-08 18:40:26 +08:00
一个状态机也就搞定了,把开始和结尾换成左右括号会方便很多。也可以是逐个字符读取,靠栈控制就可以完成。lisp 语法本来就是 AST 的表示。
1608637229
2019-09-09 15:21:30 +08:00
#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

TreeNode* helper(string& s, int i, int j) {
TreeNode* head = nullptr;
if (i > j) return head;
int cur = 0;
while (s[i] >= '0' && s[i] <= '9') {
cur += 10 * cur + s[i] - '0';
++i;
}
head = new TreeNode(cur);
int cnt = 0, k = i + 1;
for (; k < j; ++k) {
if (s[k] == '(') ++cnt;
else if (s[k] == ')') --cnt;
else if (s[k] == ',' && !cnt) break;
}
head->left = helper(s, i + 1, k - 1);
head->right = helper(s, k + 1, j - 1);
return head;
}

TreeNode* trans(string& str) {
if (str.empty()) return nullptr;
return helper(str, 0, str.size() - 1);
}


//先序遍历二叉树
void preOrder(TreeNode* root)
{
if (root == NULL) return;
cout << root->val << " ";
preOrder(root->left);
preOrder(root->right);
}


int main()
{
//测试
string str = "1(2(3,4(,5)),6(7,))";
TreeNode* root = trans(str);
preOrder(root);
cout << endl;
system("pause");
return 0;
}

只能想到暴力了。全部复制过来了,每次都找到那个可以确认分开为左右子树的','.
只测试了通过了这个用例。其他用例我就不知道能不能过了。
autogen
2019-09-11 10:28:03 +08:00
#ㅤcoding=utf-8


classㅤBinTreeNode:
ㅤㅤㅤㅤdefㅤ__init__(self,ㅤvalue=None):
ㅤㅤㅤㅤㅤㅤㅤㅤself.valueㅤ=ㅤvalue
ㅤㅤㅤㅤㅤㅤㅤㅤself.leftㅤ=ㅤNone
ㅤㅤㅤㅤㅤㅤㅤㅤself.rightㅤ=ㅤNone
ㅤㅤㅤㅤㅤㅤㅤㅤself.parentㅤ=ㅤNone

ㅤㅤㅤㅤdefㅤaddLeft(self,ㅤnode):
ㅤㅤㅤㅤㅤㅤㅤㅤself.leftㅤ=ㅤnode
ㅤㅤㅤㅤㅤㅤㅤㅤnode.parentㅤ=ㅤself

ㅤㅤㅤㅤdefㅤaddRight(self,ㅤnode):
ㅤㅤㅤㅤㅤㅤㅤㅤself.rightㅤ=ㅤnode
ㅤㅤㅤㅤㅤㅤㅤㅤnode.parentㅤ=ㅤself

ㅤㅤㅤㅤdefㅤ__str__(self):
ㅤㅤㅤㅤㅤㅤㅤㅤstrNodeㅤ=ㅤ"v[%d]"ㅤ%ㅤself.value
ㅤㅤㅤㅤㅤㅤㅤㅤifㅤself.leftㅤisㅤnotㅤNone:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤstrNodeㅤ+=ㅤ"ㅤl[%d]"ㅤ%ㅤself.left.value
ㅤㅤㅤㅤㅤㅤㅤㅤifㅤself.rightㅤisㅤnotㅤNone:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤstrNodeㅤ+=ㅤ"ㅤr[%d]"ㅤ%ㅤself.right.value
ㅤㅤㅤㅤㅤㅤㅤㅤreturnㅤstrNode


classㅤStack:
ㅤㅤㅤㅤdefㅤ__init__(self):
ㅤㅤㅤㅤㅤㅤㅤㅤself.listㅤ=ㅤ[]

ㅤㅤㅤㅤdefㅤpush(self,ㅤdata):
ㅤㅤㅤㅤㅤㅤㅤㅤself.list.append(data)

ㅤㅤㅤㅤdefㅤpop(self):
ㅤㅤㅤㅤㅤㅤㅤㅤdataㅤ=ㅤself.list[-1]
ㅤㅤㅤㅤㅤㅤㅤㅤself.list.pop(-1)
ㅤㅤㅤㅤㅤㅤㅤㅤreturnㅤdata

ㅤㅤㅤㅤdefㅤtop(self):
ㅤㅤㅤㅤㅤㅤㅤㅤifㅤself.empty():
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤreturnㅤNone
ㅤㅤㅤㅤㅤㅤㅤㅤelse:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤreturnㅤself.list[-1]

ㅤㅤㅤㅤdefㅤempty(self):
ㅤㅤㅤㅤㅤㅤㅤㅤreturnㅤlen(self.list)ㅤ==ㅤ0


classㅤBinTreeParser:
ㅤㅤㅤㅤdefㅤ__init__(self,ㅤs):
ㅤㅤㅤㅤㅤㅤㅤㅤself.inStrㅤ=ㅤs
ㅤㅤㅤㅤㅤㅤㅤㅤself.lenStrㅤ=ㅤlen(s)
ㅤㅤㅤㅤㅤㅤㅤㅤself.idxStrㅤ=ㅤ0
ㅤㅤㅤㅤㅤㅤㅤㅤself.rootㅤ=ㅤNone
ㅤㅤㅤㅤㅤㅤㅤㅤself.symbolicㅤ=ㅤ0ㅤㅤ#ㅤ0:num,ㅤ1:openParen,ㅤ2:comma,ㅤ3:closeParen

ㅤㅤㅤㅤdefㅤparseSymbolic(self):
ㅤㅤㅤㅤㅤㅤㅤㅤifㅤself.inStr[self.idxStr]ㅤ==ㅤ'(':
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤself.symbolicㅤ=ㅤ1
ㅤㅤㅤㅤㅤㅤㅤㅤelifㅤself.inStr[self.idxStr]ㅤ==ㅤ',':
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤself.symbolicㅤ=ㅤ2
ㅤㅤㅤㅤㅤㅤㅤㅤelifㅤself.inStr[self.idxStr]ㅤ==ㅤ')':
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤself.symbolicㅤ=ㅤ3
ㅤㅤㅤㅤㅤㅤㅤㅤelse:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤnumㅤ=ㅤ0
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤwhileㅤ'0'ㅤ<=ㅤself.inStr[self.idxStr]ㅤ<=ㅤ'9':
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤnumㅤ*=ㅤ10
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤnumㅤ+=ㅤint(self.inStr[self.idxStr])ㅤ-ㅤint('0')
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤself.idxStrㅤ+=ㅤ1
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤself.symbolicㅤ=ㅤ0
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤreturnㅤnum
ㅤㅤㅤㅤㅤㅤㅤㅤifㅤself.symbolicㅤ!=ㅤ0:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤself.idxStrㅤ+=ㅤ1
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤreturnㅤ0

ㅤㅤㅤㅤdefㅤparse(self):
ㅤㅤㅤㅤㅤㅤㅤㅤrootStackㅤ=ㅤStack()
ㅤㅤㅤㅤㅤㅤㅤㅤcurRootㅤ=ㅤNone
ㅤㅤㅤㅤㅤㅤㅤㅤcurNodeㅤ=ㅤNone
ㅤㅤㅤㅤㅤㅤㅤㅤstateㅤ=ㅤ0

ㅤㅤㅤㅤㅤㅤㅤㅤwhileㅤself.idxStrㅤ<ㅤself.lenStr:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤnumㅤ=ㅤself.parseSymbolic()
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤifㅤself.symbolicㅤ==ㅤ0:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤcurNodeㅤ=ㅤBinTreeNode(num)
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤifㅤstateㅤ==ㅤ1:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤcurRoot.addLeft(curNode)
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤelifㅤstateㅤ==ㅤ2:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤcurRoot.addRight(curNode)
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤelifㅤself.symbolicㅤ==ㅤ1:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤstateㅤ=ㅤ1
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤrootStack.push(curNode)
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤcurRootㅤ=ㅤcurNode
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤifㅤself.rootㅤisㅤNone:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤself.rootㅤ=ㅤcurRoot
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤelifㅤself.symbolicㅤ==ㅤ2:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤstateㅤ=ㅤ2
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤelifㅤself.symbolicㅤ==ㅤ3:
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤrootStack.pop()
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤcurRootㅤ=ㅤrootStack.top()
ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤstateㅤ=ㅤ3


#ㅤexample:ㅤ'100(200(300,400(,500)),600(700,))'
ifㅤ__name__ㅤ==ㅤ'__main__':
ㅤㅤㅤㅤinStrㅤ=ㅤinput("输入要转换的字符串:")
ㅤㅤㅤㅤparserㅤ=ㅤBinTreeParser(inStr)
ㅤㅤㅤㅤparser.parse()
ㅤㅤㅤㅤprint("pause")





#

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/598732

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX