-
-
Notifications
You must be signed in to change notification settings - Fork 8.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add ts solution to lc problem: No.323 #2990
Conversation
🤭 感谢你的提交,请检查你的改动是否符合以下项目规范。 1. 格式化我们项目中各种编程语言代码(包括文档)所采用的格式化工具不同,提交 pr 之前必须确保代码、文档正确格式化。
2. Git 提交信息我们项目遵循 AngularJS Git Commit Message Conventions 规范,我们希望你的提交信息尽可能与项目保持一致。
3. 其它补充新增题解及代码时,需要创建 Solution.xxx 源代码文件(如果已存在,请确认算法是否更优,是则覆盖已有算法代码),同时,需要在 README.md 以及 README_EN.md 中添加对应的代码片段(英文文件中不要出现中文注释) 🤭 Thank you for your contribution. Please check if your changes comply with the following project specifications. 1. FormattingWe use different formatting tools for various programming languages (including documentation) in our project. You must ensure that the code and documentation are correctly formatted before submitting a pr.
2. Git Commit MessageOur project follows the AngularJS Git Commit Message Conventions. We hope that your submission information is as consistent as possible with the project.
3. Other notesWhen adding solutions and code, you need to create a Solution.xxx source code file (if it already exists, please confirm whether the algorithm is better, if yes, overwrite the existing algorithm code), and at the same time, you need to add the corresponding code snippets in README.md and README_EN.md (do not have Chinese comments in the English file) |
} | ||
}; | ||
|
||
for (const i of Object.keys(g)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a for loop, there is no need to use Object.keys(g). Since the length of g is n, you can just use for (let i = 0; i < n; i++).
The advantage of this is that you can not use +
to turn the number type, easier to read for newcomers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice advice, thanks a lot!
Sometimes old and time-tested solutions begin to be forgotten )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's nice to meet TS developers in this repository to discuss more elegant code together. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s mutual )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're both React users as well, so maybe there's a lot more to discuss in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, and I am with React ecosystem since Nov. 2016, but with a few interruptions )
for (const i of Object.keys(g)) { | ||
if (vis.has(+i)) continue; | ||
|
||
dfs(+i); | ||
ans++; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (const i of Object.keys(g)) { | |
if (vis.has(+i)) continue; | |
dfs(+i); | |
ans++; | |
} | |
for (let i = 0; i < n; i++) { | |
if (!vis.has(i)) { | |
dfs(i); | |
ans++; | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a code readability point of view, if (!vis.has(i)) { dfs(i); ans++; }
might be better. This is because it explicitly expresses the logic of “if node i has not been visited, perform DFS and increase the number of connected components”, instead of using continue to skip nodes that have already been visited. This makes the logic of the code clearer and easier to understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the 1st glance yes, but... let't look from another point of view.
Every algorithm in most case is transformation input data into output.
And all the data can be considered as valid and invalid (simple binary choiсe, like in the "Matrix" movie))) And when invalid data rejected as early as possible common structure of the algorithm becomes more "flat", and cyclomatic and cognitive complexity is reduced. Also it is possible to draw an analogy with the domain of definition of a function from the school course of math. That is why usually I am trying to throw away wrong cases as early as possible. Also this approach is called as "eager return", and it shows itself in all its glory in the case of a large amount of code.
And I am agree, in the current task it's advantages are not so obvious. But I am using it out of habbit over the years.
And also it make sense to add that you shouldn't make every good rule in absolut. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with you that continue
is indeed pretty much the same whether to change it or not, there are pros and cons to each, and it's arguably a bit simpler to show if you don't use it over here. But Object.keys(g) needs to be changed, and I see that you've changed it as well.
The reason is as follows:
Performance: object.keys(g) creates a new array containing all the keys of g, which takes extra time and space. In contrast, for (let i = 0; i < n; i++) simply traverses a range, which is better performance.
Readability: for (let i = 0; i < n; i++) clearly expresses the range you want to traverse (from 0 to n-1), whereas const i of Object.keys(g) requires the reader to know that g is an object whose keys are the elements you want to traverse.
Type safety: in const i of Object.keys(g), i is a string, even though the keys of g are actually numbers. This can lead to type errors; for example, you may need to use +i to convert i to a number. In contrast, i in for (let i = 0; i < n; i++) is always a number, and there are no type problems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am agree with you, and thank you for explanation.
if (vis.has(+i)) continue; | ||
|
||
dfs(+i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i
is a number, so you don't need to use + to convert it.
if (vis.has(+i)) continue; | |
dfs(+i); | |
if (vis.has(i)) continue; | |
dfs(i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, just forgot to remove
You don't need to care about the language section, just look at the code section and fill in the same positions |
I did (I hope). Please check PR again. |
The submitted PR actually uses the DFS method, not BFS. A DFS solution is already provided in Solution 1. Therefore, I am considering reverting this PR. Thank you for your contribution. @rain84 |
Hi @yanglbme No problem ) But what makes you think it's DFS? |
BFS usually uses a queue and is implemented iteratively, whereas DFS typically uses recursion and requires the system to allocate stack space. |
I added a new BFS implementation in PR #2991 |
Ohh, I see. |
Let me simplify your solution ) |
No description provided.