Skip to content

feat: update lc problems #3679

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

Merged
merged 1 commit into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
721 changes: 610 additions & 111 deletions solution/0600-0699/0685.Redundant Connection II/README.md

Large diffs are not rendered by default.

723 changes: 613 additions & 110 deletions solution/0600-0699/0685.Redundant Connection II/README_EN.md

Large diffs are not rendered by default.

75 changes: 35 additions & 40 deletions solution/0600-0699/0685.Redundant Connection II/Solution.cpp
Original file line number Diff line number Diff line change
@@ -1,48 +1,43 @@
class UnionFind {
public:
vector<int> p;
int n;

UnionFind(int _n)
: n(_n)
, p(_n) {
iota(p.begin(), p.end(), 0);
}

bool unite(int a, int b) {
int pa = find(a), pb = find(b);
if (pa == pb) return false;
p[pa] = pb;
--n;
return true;
}

int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
};

class Solution {
public:
vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {
int n = edges.size();
vector<int> p(n + 1);
for (int i = 0; i <= n; ++i) p[i] = i;
UnionFind uf(n + 1);
int conflict = -1, cycle = -1;
vector<int> ind(n);
for (const auto& e : edges) {
++ind[e[1] - 1];
}
vector<int> dup;
for (int i = 0; i < n; ++i) {
int u = edges[i][0], v = edges[i][1];
if (p[v] != v)
conflict = i;
else {
p[v] = u;
if (!uf.unite(u, v)) cycle = i;
if (ind[edges[i][1] - 1] == 2) {
dup.push_back(i);
}
}
if (conflict == -1) return edges[cycle];
int v = edges[conflict][1];
if (cycle != -1) return {p[v], v};
return edges[conflict];
vector<int> p(n);
iota(p.begin(), p.end(), 0);
function<int(int)> find = [&](int x) {
return x == p[x] ? x : p[x] = find(p[x]);
};
if (!dup.empty()) {
for (int i = 0; i < n; ++i) {
if (i == dup[1]) {
continue;
}
int pu = find(edges[i][0] - 1);
int pv = find(edges[i][1] - 1);
if (pu == pv) {
return edges[dup[0]];
}
p[pu] = pv;
}
return edges[dup[1]];
}
for (int i = 0;; ++i) {
int pu = find(edges[i][0] - 1);
int pv = find(edges[i][1] - 1);
if (pu == pv) {
return edges[i];
}
p[pu] = pv;
}
}
};
};
84 changes: 36 additions & 48 deletions solution/0600-0699/0685.Redundant Connection II/Solution.go
Original file line number Diff line number Diff line change
@@ -1,57 +1,45 @@
type unionFind struct {
p []int
n int
}

func newUnionFind(n int) *unionFind {
p := make([]int, n)
for i := range p {
p[i] = i
}
return &unionFind{p, n}
}

func (uf *unionFind) find(x int) int {
if uf.p[x] != x {
uf.p[x] = uf.find(uf.p[x])
}
return uf.p[x]
}

func (uf *unionFind) union(a, b int) bool {
if uf.find(a) == uf.find(b) {
return false
}
uf.p[uf.find(a)] = uf.find(b)
uf.n--
return true
}

func findRedundantDirectedConnection(edges [][]int) []int {
n := len(edges)
p := make([]int, n+1)
ind := make([]int, n)
for _, e := range edges {
ind[e[1]-1]++
}
dup := []int{}
for i, e := range edges {
if ind[e[1]-1] == 2 {
dup = append(dup, i)
}
}
p := make([]int, n)
for i := range p {
p[i] = i
}
uf := newUnionFind(n + 1)
conflict, cycle := -1, -1
for i, e := range edges {
u, v := e[0], e[1]
if p[v] != v {
conflict = i
} else {
p[v] = u
if !uf.union(u, v) {
cycle = i
}
var find func(int) int
find = func(x int) int {
if p[x] != x {
p[x] = find(p[x])
}
return p[x]
}
if conflict == -1 {
return edges[cycle]
if len(dup) > 0 {
for i, e := range edges {
if i == dup[1] {
continue
}
pu, pv := find(e[0]-1), find(e[1]-1)
if pu == pv {
return edges[dup[0]]
}
p[pu] = pv
}
return edges[dup[1]]
}
v := edges[conflict][1]
if cycle != -1 {
return []int{p[v], v}
for _, e := range edges {
pu, pv := find(e[0]-1), find(e[1]-1)
if pu == pv {
return e
}
p[pu] = pv
}
return edges[conflict]
}
return nil
}
77 changes: 32 additions & 45 deletions solution/0600-0699/0685.Redundant Connection II/Solution.java
Original file line number Diff line number Diff line change
@@ -1,61 +1,48 @@
class Solution {
private int[] p;

public int[] findRedundantDirectedConnection(int[][] edges) {
int n = edges.length;
int[] p = new int[n + 1];
for (int i = 0; i <= n; ++i) {
p[i] = i;
}
UnionFind uf = new UnionFind(n + 1);
int conflict = -1, cycle = -1;
for (int i = 0; i < n; ++i) {
int u = edges[i][0], v = edges[i][1];
if (p[v] != v) {
conflict = i;
} else {
p[v] = u;
if (!uf.union(u, v)) {
cycle = i;
}
}
int[] ind = new int[n];
for (var e : edges) {
++ind[e[1] - 1];
}
if (conflict == -1) {
return edges[cycle];
}
int v = edges[conflict][1];
if (cycle != -1) {
return new int[] {p[v], v};
}
return edges[conflict];
}
}

class UnionFind {
public int[] p;
public int n;

public UnionFind(int n) {
List<Integer> dup = new ArrayList<>();
p = new int[n];
for (int i = 0; i < n; ++i) {
if (ind[edges[i][1] - 1] == 2) {
dup.add(i);
}
p[i] = i;
}
this.n = n;
}

public boolean union(int a, int b) {
int pa = find(a);
int pb = find(b);
if (pa == pb) {
return false;
if (!dup.isEmpty()) {
for (int i = 0; i < n; ++i) {
if (i == dup.get(1)) {
continue;
}
int pu = find(edges[i][0] - 1);
int pv = find(edges[i][1] - 1);
if (pu == pv) {
return edges[dup.get(0)];
}
p[pu] = pv;
}
return edges[dup.get(1)];
}
for (int i = 0;; ++i) {
int pu = find(edges[i][0] - 1);
int pv = find(edges[i][1] - 1);
if (pu == pv) {
return edges[i];
}
p[pu] = pv;
}
p[pa] = pb;
--n;
return true;
}

public int find(int x) {
private int find(int x) {
if (p[x] != x) {
p[x] = find(p[x]);
}
return p[x];
}
}
}
44 changes: 44 additions & 0 deletions solution/0600-0699/0685.Redundant Connection II/Solution.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* @param {number[][]} edges
* @return {number[]}
*/
var findRedundantDirectedConnection = function (edges) {
const n = edges.length;
const ind = Array(n).fill(0);
for (const [_, v] of edges) {
++ind[v - 1];
}
const dup = [];
for (let i = 0; i < n; ++i) {
if (ind[edges[i][1] - 1] === 2) {
dup.push(i);
}
}
const p = Array.from({ length: n }, (_, i) => i);
const find = x => {
if (p[x] !== x) {
p[x] = find(p[x]);
}
return p[x];
};
if (dup.length) {
for (let i = 0; i < n; ++i) {
if (i === dup[1]) {
continue;
}
const [pu, pv] = [find(edges[i][0] - 1), find(edges[i][1] - 1)];
if (pu === pv) {
return edges[dup[0]];
}
p[pu] = pv;
}
return edges[dup[1]];
}
for (let i = 0; ; ++i) {
const [pu, pv] = [find(edges[i][0] - 1), find(edges[i][1] - 1)];
if (pu === pv) {
return edges[i];
}
p[pu] = pv;
}
};
56 changes: 23 additions & 33 deletions solution/0600-0699/0685.Redundant Connection II/Solution.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,27 @@
class UnionFind:
def __init__(self, n):
self.p = list(range(n))
self.n = n

def union(self, a, b):
if self.find(a) == self.find(b):
return False
self.p[self.find(a)] = self.find(b)
self.n -= 1
return True

def find(self, x):
if self.p[x] != x:
self.p[x] = self.find(self.p[x])
return self.p[x]


class Solution:
def findRedundantDirectedConnection(self, edges: List[List[int]]) -> List[int]:
def find(x: int) -> int:
if p[x] != x:
p[x] = find(p[x])
return p[x]

n = len(edges)
p = list(range(n + 1))
uf = UnionFind(n + 1)
conflict = cycle = None
ind = [0] * n
for _, v in edges:
ind[v - 1] += 1
dup = [i for i, (_, v) in enumerate(edges) if ind[v - 1] == 2]
p = list(range(n))
if dup:
for i, (u, v) in enumerate(edges):
if i == dup[1]:
continue
pu, pv = find(u - 1), find(v - 1)
if pu == pv:
return edges[dup[0]]
p[pu] = pv
return edges[dup[1]]
for i, (u, v) in enumerate(edges):
if p[v] != v:
conflict = i
else:
p[v] = u
if not uf.union(u, v):
cycle = i
if conflict is None:
return edges[cycle]
v = edges[conflict][1]
if cycle is not None:
return [p[v], v]
return edges[conflict]
pu, pv = find(u - 1), find(v - 1)
if pu == pv:
return edges[i]
p[pu] = pv
Loading
Loading