From bac33bba6aed06c007be8a29d2e78c1b53ea1536 Mon Sep 17 00:00:00 2001 From: Samarth Swami <70163465+samarthswami1016@users.noreply.github.com> Date: Tue, 11 Mar 2025 19:19:40 +0530 Subject: [PATCH 01/13] Update README.md --- .../3400-3499/3470.Permutations IV/README.md | 324 +++++++++++++++++- 1 file changed, 320 insertions(+), 4 deletions(-) diff --git a/solution/3400-3499/3470.Permutations IV/README.md b/solution/3400-3499/3470.Permutations IV/README.md index bceccae2ecccc..19d074f0d1f3e 100644 --- a/solution/3400-3499/3470.Permutations IV/README.md +++ b/solution/3400-3499/3470.Permutations IV/README.md @@ -111,25 +111,341 @@ tags: #### Python3 ```python - +from typing import List +from math import factorial +import heapq + +class Solution: + def permute(self, xxy: int, yyz: int) -> List[int]: + + kasu = {} + nnss = [] + majs = [] + ajwi = heapq.heappush + laoq = [] + + zzp = [i for i in range(1, xxy + 1) if i % 2 == 1] + zzq = [i for i in range(1, xxy + 1) if i % 2 == 0] + + ppp = [] + nxr = None + + for pps in range(xxy): + if pps == 0: + cnd = sorted(zzp + zzq) + else: + cnd = zzp if nxr == 1 else zzq + + fff = False + for cndt in cnd: + if cndt % 2 == 1: + nxt = 0 + noo = len(zzp) - 1 + nee = len(zzq) + else: + nxt = 1 + noo = len(zzp) + nee = len(zzq) - 1 + + llq = noo + nee + if llq == 0: + cnt = 1 + else: + if nxt == 1: + if noo != (llq + 1) // 2 or nee != llq // 2: + cnt = 0 + else: + cnt = factorial(noo) * factorial(nee) + else: + if nee != (llq + 1) // 2 or noo != llq // 2: + cnt = 0 + else: + cnt = factorial(noo) * factorial(nee) + + ajwi(nnss, cnt) + ajwi(majs, llq) + + if cnt >= yyz: + ppp.append(cndt) + if cndt % 2 == 1: + zzp.remove(cndt) + nxr = 0 + else: + zzq.remove(cndt) + nxr = 1 + fff = True + break + else: + yyz -= cnt + + ajwi(laoq, len(ppp)) + + if not fff: + return [] + return ppp ``` #### Java ```java - +import java.util.*; + +class DPHelper { + static final long ok = 10000000000000000L; + long[][][] dp = new long[101][101][2]; + boolean[][][] vis = new boolean[101][101][2]; + + long compute(int o, int e, int p) { + if (o == 0 && e == 0) return 1; + if (vis[o][e][p]) return dp[o][e][p]; + + long r = 0; + if (p == 1) { + if (o == 0) r = 0; + else r = o * compute(o - 1, e, 0); + } else { + if (e == 0) r = 0; + else r = e * compute(o, e - 1, 1); + } + + if (r > ok) r = ok; + vis[o][e][p] = true; + dp[o][e][p] = r; + return r; + } +} + +class SortHelper { + void sortList(ArrayList list) { + Collections.sort(list); + } +} + +class PermutationHelper { + List buildPermutation(int p, ArrayList O, ArrayList E, long k, DPHelper d) { + List ans = new ArrayList<>(); + if (O.size() + E.size() == 0) return ans; + int i = 0; + + if (p == 1) { + while (i < O.size()) { + long cnt = d.compute(O.size() - 1, E.size(), 0); + if (k > cnt) { + k -= cnt; + i++; + } else { + int x = O.get(i); + O.remove(i); + ans.add(x); + ans.addAll(buildPermutation(0, O, E, k, d)); + return ans; + } + } + } else { + while (i < E.size()) { + long cnt = d.compute(O.size(), E.size() - 1, 1); + if (k > cnt) { + k -= cnt; + i++; + } else { + int x = E.get(i); + E.remove(i); + ans.add(x); + ans.addAll(buildPermutation(1, O, E, k, d)); + return ans; + } + } + } + return ans; + } + + List alternateFormation(ArrayList O, ArrayList E, long k, DPHelper d, int n, SortHelper s) { + List ans = new ArrayList<>(); + int tot = O.size() + E.size(); + if (tot % 2 == 1) { + int i = 0; + while (i < O.size()) { + long cnt = d.compute(O.size() - 1, E.size(), 0); + if (k > cnt) { + k -= cnt; + } else { + int x = O.get(i); + O.remove(i); + ans.add(x); + ans.addAll(buildPermutation(0, O, E, k, d)); + return ans; + } + i++; + } + } else { + ArrayList U = new ArrayList<>(); + U.addAll(O); + U.addAll(E); + s.sortList(U); + int i = 0; + while (i < U.size()) { + int x = U.get(i); + if (O.contains(x)) { + long cnt = d.compute(O.size() - 1, E.size(), 0); + if (k > cnt) { + k -= cnt; + } else { + int idx = O.indexOf(x); + O.remove(idx); + ans.add(x); + ans.addAll(buildPermutation(0, O, E, k, d)); + return ans; + } + } else { + long cnt = d.compute(O.size(), E.size() - 1, 1); + if (k > cnt) { + k -= cnt; + } else { + int idx = E.indexOf(x); + E.remove(idx); + ans.add(x); + ans.addAll(buildPermutation(1, O, E, k, d)); + return ans; + } + } + i++; + } + } + return ans; + } +} + +class Solution { + public int[] permute(int n, long k) { + int o = (n + 1) / 2, e = n / 2; + ArrayList O = new ArrayList<>(), E = new ArrayList<>(); + + for (int i = 1; i <= n; i++) { + if (i % 2 == 1) O.add(i); + else E.add(i); + } + + SortHelper s = new SortHelper(); + s.sortList(O); + s.sortList(E); + + DPHelper d = new DPHelper(); + PermutationHelper ph = new PermutationHelper(); + + long tot = 0; + if (n % 2 == 1) tot = d.compute(O.size() - 1, E.size(), 0) * O.size(); + else tot = d.compute(O.size() - 1, E.size(), 0) * O.size() + d.compute(O.size(), E.size() - 1, 1) * E.size(); + + if (k > tot) return new int[0]; + + List res = ph.alternateFormation(O, E, k, d, n, s); + int[] ans = new int[res.size()]; + for (int i = 0; i < res.size(); i++) ans[i] = res.get(i); + + return ans; + } +} ``` #### C++ ```cpp - +class Solution { + long long f[105]; +public: + vector permute(int n, long long k) { + int i,j; + for(i=f[0]=1;i<=n;i++)if(f[i-1]>=k)f[i]=k; + else f[i]=f[i-1]*(i+1>>1); + if(!(n&1))f[n]*=2; + if(f[n] ans(n),a[2]; + for(i=0;i= k { + f[i] = k + } else { + f[i] = f[i-1] * int64((i+1)>>1) + } + } + if n%2 == 0 { + f[n] *= 2 + } + if f[n] < k { + return []int{} + } + k-- + ans := make([]int, n) + a := [2][]int{} + for i := 0; i < n; i++ { + a[i&1] = append(a[i&1], i) + } + + if n%2 == 1 { + ans[0] = int(k/f[n-1]) * 2 + k -= int64(ans[0]/2) * f[n-1] + } else { + ans[0] = int(k / f[n-1]) + k -= int64(ans[0]) * f[n-1] + } + + index := sort.SearchInts(a[ans[0]&1], ans[0]) + a[ans[0]&1] = append(a[ans[0]&1][:index], a[ans[0]&1][index+1:]...) + + for i := 1; i < n; i++ { + if n%2 == 1 { + ans[i] = a[i&1][k/f[n-i-1]] + } else { + ans[i] = a[(ans[0]^i)&1][k/f[n-i-1]] + } + k %= f[n-i-1] + + index = sort.SearchInts(a[ans[i]&1], ans[i]) + a[ans[i]&1] = append(a[ans[i]&1][:index], a[ans[i]&1][index+1:]...) + } + + for i := 0; i < n; i++ { + ans[i]++ + } + return ans +} ``` From 4f2027d737c311654ce90f47bab063aa305d1088 Mon Sep 17 00:00:00 2001 From: Samarth Swami <70163465+samarthswami1016@users.noreply.github.com> Date: Tue, 11 Mar 2025 19:20:59 +0530 Subject: [PATCH 02/13] Update README_EN.md --- .../3470.Permutations IV/README_EN.md | 324 +++++++++++++++++- 1 file changed, 320 insertions(+), 4 deletions(-) diff --git a/solution/3400-3499/3470.Permutations IV/README_EN.md b/solution/3400-3499/3470.Permutations IV/README_EN.md index 012612842b115..41f4654168597 100644 --- a/solution/3400-3499/3470.Permutations IV/README_EN.md +++ b/solution/3400-3499/3470.Permutations IV/README_EN.md @@ -108,25 +108,341 @@ tags: #### Python3 ```python - +from typing import List +from math import factorial +import heapq + +class Solution: + def permute(self, xxy: int, yyz: int) -> List[int]: + + kasu = {} + nnss = [] + majs = [] + ajwi = heapq.heappush + laoq = [] + + zzp = [i for i in range(1, xxy + 1) if i % 2 == 1] + zzq = [i for i in range(1, xxy + 1) if i % 2 == 0] + + ppp = [] + nxr = None + + for pps in range(xxy): + if pps == 0: + cnd = sorted(zzp + zzq) + else: + cnd = zzp if nxr == 1 else zzq + + fff = False + for cndt in cnd: + if cndt % 2 == 1: + nxt = 0 + noo = len(zzp) - 1 + nee = len(zzq) + else: + nxt = 1 + noo = len(zzp) + nee = len(zzq) - 1 + + llq = noo + nee + if llq == 0: + cnt = 1 + else: + if nxt == 1: + if noo != (llq + 1) // 2 or nee != llq // 2: + cnt = 0 + else: + cnt = factorial(noo) * factorial(nee) + else: + if nee != (llq + 1) // 2 or noo != llq // 2: + cnt = 0 + else: + cnt = factorial(noo) * factorial(nee) + + ajwi(nnss, cnt) + ajwi(majs, llq) + + if cnt >= yyz: + ppp.append(cndt) + if cndt % 2 == 1: + zzp.remove(cndt) + nxr = 0 + else: + zzq.remove(cndt) + nxr = 1 + fff = True + break + else: + yyz -= cnt + + ajwi(laoq, len(ppp)) + + if not fff: + return [] + return ppp ``` #### Java ```java - +import java.util.*; + +class DPHelper { + static final long ok = 10000000000000000L; + long[][][] dp = new long[101][101][2]; + boolean[][][] vis = new boolean[101][101][2]; + + long compute(int o, int e, int p) { + if (o == 0 && e == 0) return 1; + if (vis[o][e][p]) return dp[o][e][p]; + + long r = 0; + if (p == 1) { + if (o == 0) r = 0; + else r = o * compute(o - 1, e, 0); + } else { + if (e == 0) r = 0; + else r = e * compute(o, e - 1, 1); + } + + if (r > ok) r = ok; + vis[o][e][p] = true; + dp[o][e][p] = r; + return r; + } +} + +class SortHelper { + void sortList(ArrayList list) { + Collections.sort(list); + } +} + +class PermutationHelper { + List buildPermutation(int p, ArrayList O, ArrayList E, long k, DPHelper d) { + List ans = new ArrayList<>(); + if (O.size() + E.size() == 0) return ans; + int i = 0; + + if (p == 1) { + while (i < O.size()) { + long cnt = d.compute(O.size() - 1, E.size(), 0); + if (k > cnt) { + k -= cnt; + i++; + } else { + int x = O.get(i); + O.remove(i); + ans.add(x); + ans.addAll(buildPermutation(0, O, E, k, d)); + return ans; + } + } + } else { + while (i < E.size()) { + long cnt = d.compute(O.size(), E.size() - 1, 1); + if (k > cnt) { + k -= cnt; + i++; + } else { + int x = E.get(i); + E.remove(i); + ans.add(x); + ans.addAll(buildPermutation(1, O, E, k, d)); + return ans; + } + } + } + return ans; + } + + List alternateFormation(ArrayList O, ArrayList E, long k, DPHelper d, int n, SortHelper s) { + List ans = new ArrayList<>(); + int tot = O.size() + E.size(); + if (tot % 2 == 1) { + int i = 0; + while (i < O.size()) { + long cnt = d.compute(O.size() - 1, E.size(), 0); + if (k > cnt) { + k -= cnt; + } else { + int x = O.get(i); + O.remove(i); + ans.add(x); + ans.addAll(buildPermutation(0, O, E, k, d)); + return ans; + } + i++; + } + } else { + ArrayList U = new ArrayList<>(); + U.addAll(O); + U.addAll(E); + s.sortList(U); + int i = 0; + while (i < U.size()) { + int x = U.get(i); + if (O.contains(x)) { + long cnt = d.compute(O.size() - 1, E.size(), 0); + if (k > cnt) { + k -= cnt; + } else { + int idx = O.indexOf(x); + O.remove(idx); + ans.add(x); + ans.addAll(buildPermutation(0, O, E, k, d)); + return ans; + } + } else { + long cnt = d.compute(O.size(), E.size() - 1, 1); + if (k > cnt) { + k -= cnt; + } else { + int idx = E.indexOf(x); + E.remove(idx); + ans.add(x); + ans.addAll(buildPermutation(1, O, E, k, d)); + return ans; + } + } + i++; + } + } + return ans; + } +} + +class Solution { + public int[] permute(int n, long k) { + int o = (n + 1) / 2, e = n / 2; + ArrayList O = new ArrayList<>(), E = new ArrayList<>(); + + for (int i = 1; i <= n; i++) { + if (i % 2 == 1) O.add(i); + else E.add(i); + } + + SortHelper s = new SortHelper(); + s.sortList(O); + s.sortList(E); + + DPHelper d = new DPHelper(); + PermutationHelper ph = new PermutationHelper(); + + long tot = 0; + if (n % 2 == 1) tot = d.compute(O.size() - 1, E.size(), 0) * O.size(); + else tot = d.compute(O.size() - 1, E.size(), 0) * O.size() + d.compute(O.size(), E.size() - 1, 1) * E.size(); + + if (k > tot) return new int[0]; + + List res = ph.alternateFormation(O, E, k, d, n, s); + int[] ans = new int[res.size()]; + for (int i = 0; i < res.size(); i++) ans[i] = res.get(i); + + return ans; + } +} ``` #### C++ ```cpp - +class Solution { + long long f[105]; +public: + vector permute(int n, long long k) { + int i,j; + for(i=f[0]=1;i<=n;i++)if(f[i-1]>=k)f[i]=k; + else f[i]=f[i-1]*(i+1>>1); + if(!(n&1))f[n]*=2; + if(f[n] ans(n),a[2]; + for(i=0;i= k { + f[i] = k + } else { + f[i] = f[i-1] * int64((i+1)>>1) + } + } + if n%2 == 0 { + f[n] *= 2 + } + if f[n] < k { + return []int{} + } + k-- + ans := make([]int, n) + a := [2][]int{} + for i := 0; i < n; i++ { + a[i&1] = append(a[i&1], i) + } + + if n%2 == 1 { + ans[0] = int(k/f[n-1]) * 2 + k -= int64(ans[0]/2) * f[n-1] + } else { + ans[0] = int(k / f[n-1]) + k -= int64(ans[0]) * f[n-1] + } + + index := sort.SearchInts(a[ans[0]&1], ans[0]) + a[ans[0]&1] = append(a[ans[0]&1][:index], a[ans[0]&1][index+1:]...) + + for i := 1; i < n; i++ { + if n%2 == 1 { + ans[i] = a[i&1][k/f[n-i-1]] + } else { + ans[i] = a[(ans[0]^i)&1][k/f[n-i-1]] + } + k %= f[n-i-1] + + index = sort.SearchInts(a[ans[i]&1], ans[i]) + a[ans[i]&1] = append(a[ans[i]&1][:index], a[ans[i]&1][index+1:]...) + } + + for i := 0; i < n; i++ { + ans[i]++ + } + return ans +} ``` From 44776a5ace7e074c5c43958814f5b6e8d27ec164 Mon Sep 17 00:00:00 2001 From: Samarth Swami <70163465+samarthswami1016@users.noreply.github.com> Date: Tue, 11 Mar 2025 19:21:36 +0530 Subject: [PATCH 03/13] Add files via upload --- .../3470.Permutations IV/solution.cpp | 40 +++++ .../3470.Permutations IV/solution.go | 51 ++++++ .../3470.Permutations IV/solution.java | 157 ++++++++++++++++++ .../3470.Permutations IV/solution.py | 72 ++++++++ 4 files changed, 320 insertions(+) create mode 100644 solution/3400-3499/3470.Permutations IV/solution.cpp create mode 100644 solution/3400-3499/3470.Permutations IV/solution.go create mode 100644 solution/3400-3499/3470.Permutations IV/solution.java create mode 100644 solution/3400-3499/3470.Permutations IV/solution.py diff --git a/solution/3400-3499/3470.Permutations IV/solution.cpp b/solution/3400-3499/3470.Permutations IV/solution.cpp new file mode 100644 index 0000000000000..d4141209a683e --- /dev/null +++ b/solution/3400-3499/3470.Permutations IV/solution.cpp @@ -0,0 +1,40 @@ +class Solution { + long long f[105]; +public: + vector permute(int n, long long k) { + int i,j; + for(i=f[0]=1;i<=n;i++)if(f[i-1]>=k)f[i]=k; + else f[i]=f[i-1]*(i+1>>1); + if(!(n&1))f[n]*=2; + if(f[n] ans(n),a[2]; + for(i=0;i= k { + f[i] = k + } else { + f[i] = f[i-1] * int64((i+1)>>1) + } + } + if n%2 == 0 { + f[n] *= 2 + } + if f[n] < k { + return []int{} + } + k-- + ans := make([]int, n) + a := [2][]int{} + for i := 0; i < n; i++ { + a[i&1] = append(a[i&1], i) + } + + if n%2 == 1 { + ans[0] = int(k/f[n-1]) * 2 + k -= int64(ans[0]/2) * f[n-1] + } else { + ans[0] = int(k / f[n-1]) + k -= int64(ans[0]) * f[n-1] + } + + index := sort.SearchInts(a[ans[0]&1], ans[0]) + a[ans[0]&1] = append(a[ans[0]&1][:index], a[ans[0]&1][index+1:]...) + + for i := 1; i < n; i++ { + if n%2 == 1 { + ans[i] = a[i&1][k/f[n-i-1]] + } else { + ans[i] = a[(ans[0]^i)&1][k/f[n-i-1]] + } + k %= f[n-i-1] + + index = sort.SearchInts(a[ans[i]&1], ans[i]) + a[ans[i]&1] = append(a[ans[i]&1][:index], a[ans[i]&1][index+1:]...) + } + + for i := 0; i < n; i++ { + ans[i]++ + } + return ans +} \ No newline at end of file diff --git a/solution/3400-3499/3470.Permutations IV/solution.java b/solution/3400-3499/3470.Permutations IV/solution.java new file mode 100644 index 0000000000000..5bb48f9c0010d --- /dev/null +++ b/solution/3400-3499/3470.Permutations IV/solution.java @@ -0,0 +1,157 @@ +import java.util.*; + +class DPHelper { + static final long ok = 10000000000000000L; + long[][][] dp = new long[101][101][2]; + boolean[][][] vis = new boolean[101][101][2]; + + long compute(int o, int e, int p) { + if (o == 0 && e == 0) return 1; + if (vis[o][e][p]) return dp[o][e][p]; + + long r = 0; + if (p == 1) { + if (o == 0) r = 0; + else r = o * compute(o - 1, e, 0); + } else { + if (e == 0) r = 0; + else r = e * compute(o, e - 1, 1); + } + + if (r > ok) r = ok; + vis[o][e][p] = true; + dp[o][e][p] = r; + return r; + } +} + +class SortHelper { + void sortList(ArrayList list) { + Collections.sort(list); + } +} + +class PermutationHelper { + List buildPermutation(int p, ArrayList O, ArrayList E, long k, DPHelper d) { + List ans = new ArrayList<>(); + if (O.size() + E.size() == 0) return ans; + int i = 0; + + if (p == 1) { + while (i < O.size()) { + long cnt = d.compute(O.size() - 1, E.size(), 0); + if (k > cnt) { + k -= cnt; + i++; + } else { + int x = O.get(i); + O.remove(i); + ans.add(x); + ans.addAll(buildPermutation(0, O, E, k, d)); + return ans; + } + } + } else { + while (i < E.size()) { + long cnt = d.compute(O.size(), E.size() - 1, 1); + if (k > cnt) { + k -= cnt; + i++; + } else { + int x = E.get(i); + E.remove(i); + ans.add(x); + ans.addAll(buildPermutation(1, O, E, k, d)); + return ans; + } + } + } + return ans; + } + + List alternateFormation(ArrayList O, ArrayList E, long k, DPHelper d, int n, SortHelper s) { + List ans = new ArrayList<>(); + int tot = O.size() + E.size(); + if (tot % 2 == 1) { + int i = 0; + while (i < O.size()) { + long cnt = d.compute(O.size() - 1, E.size(), 0); + if (k > cnt) { + k -= cnt; + } else { + int x = O.get(i); + O.remove(i); + ans.add(x); + ans.addAll(buildPermutation(0, O, E, k, d)); + return ans; + } + i++; + } + } else { + ArrayList U = new ArrayList<>(); + U.addAll(O); + U.addAll(E); + s.sortList(U); + int i = 0; + while (i < U.size()) { + int x = U.get(i); + if (O.contains(x)) { + long cnt = d.compute(O.size() - 1, E.size(), 0); + if (k > cnt) { + k -= cnt; + } else { + int idx = O.indexOf(x); + O.remove(idx); + ans.add(x); + ans.addAll(buildPermutation(0, O, E, k, d)); + return ans; + } + } else { + long cnt = d.compute(O.size(), E.size() - 1, 1); + if (k > cnt) { + k -= cnt; + } else { + int idx = E.indexOf(x); + E.remove(idx); + ans.add(x); + ans.addAll(buildPermutation(1, O, E, k, d)); + return ans; + } + } + i++; + } + } + return ans; + } +} + +class Solution { + public int[] permute(int n, long k) { + int o = (n + 1) / 2, e = n / 2; + ArrayList O = new ArrayList<>(), E = new ArrayList<>(); + + for (int i = 1; i <= n; i++) { + if (i % 2 == 1) O.add(i); + else E.add(i); + } + + SortHelper s = new SortHelper(); + s.sortList(O); + s.sortList(E); + + DPHelper d = new DPHelper(); + PermutationHelper ph = new PermutationHelper(); + + long tot = 0; + if (n % 2 == 1) tot = d.compute(O.size() - 1, E.size(), 0) * O.size(); + else tot = d.compute(O.size() - 1, E.size(), 0) * O.size() + d.compute(O.size(), E.size() - 1, 1) * E.size(); + + if (k > tot) return new int[0]; + + List res = ph.alternateFormation(O, E, k, d, n, s); + int[] ans = new int[res.size()]; + for (int i = 0; i < res.size(); i++) ans[i] = res.get(i); + + return ans; + } +} \ No newline at end of file diff --git a/solution/3400-3499/3470.Permutations IV/solution.py b/solution/3400-3499/3470.Permutations IV/solution.py new file mode 100644 index 0000000000000..d1f02ccafb6d6 --- /dev/null +++ b/solution/3400-3499/3470.Permutations IV/solution.py @@ -0,0 +1,72 @@ +from typing import List +from math import factorial +import heapq + +class Solution: + def permute(self, xxy: int, yyz: int) -> List[int]: + + kasu = {} + nnss = [] + majs = [] + ajwi = heapq.heappush + laoq = [] + + zzp = [i for i in range(1, xxy + 1) if i % 2 == 1] + zzq = [i for i in range(1, xxy + 1) if i % 2 == 0] + + ppp = [] + nxr = None + + for pps in range(xxy): + if pps == 0: + cnd = sorted(zzp + zzq) + else: + cnd = zzp if nxr == 1 else zzq + + fff = False + for cndt in cnd: + if cndt % 2 == 1: + nxt = 0 + noo = len(zzp) - 1 + nee = len(zzq) + else: + nxt = 1 + noo = len(zzp) + nee = len(zzq) - 1 + + llq = noo + nee + if llq == 0: + cnt = 1 + else: + if nxt == 1: + if noo != (llq + 1) // 2 or nee != llq // 2: + cnt = 0 + else: + cnt = factorial(noo) * factorial(nee) + else: + if nee != (llq + 1) // 2 or noo != llq // 2: + cnt = 0 + else: + cnt = factorial(noo) * factorial(nee) + + ajwi(nnss, cnt) + ajwi(majs, llq) + + if cnt >= yyz: + ppp.append(cndt) + if cndt % 2 == 1: + zzp.remove(cndt) + nxr = 0 + else: + zzq.remove(cndt) + nxr = 1 + fff = True + break + else: + yyz -= cnt + + ajwi(laoq, len(ppp)) + + if not fff: + return [] + return ppp \ No newline at end of file From cecfdab4d9379ef0cd9891f292c87d9aa8323ff1 Mon Sep 17 00:00:00 2001 From: samarthswami1016 <70163465+samarthswami1016@users.noreply.github.com> Date: Tue, 11 Mar 2025 14:39:51 +0000 Subject: [PATCH 04/13] style: format code and docs with prettier --- .../3400-3499/3470.Permutations IV/README.md | 18 +++++++++--------- .../3470.Permutations IV/README_EN.md | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/solution/3400-3499/3470.Permutations IV/README.md b/solution/3400-3499/3470.Permutations IV/README.md index 19d074f0d1f3e..f530d2870c0c7 100644 --- a/solution/3400-3499/3470.Permutations IV/README.md +++ b/solution/3400-3499/3470.Permutations IV/README.md @@ -117,18 +117,18 @@ import heapq class Solution: def permute(self, xxy: int, yyz: int) -> List[int]: - - kasu = {} + + kasu = {} nnss = [] majs = [] ajwi = heapq.heappush laoq = [] - + zzp = [i for i in range(1, xxy + 1) if i % 2 == 1] zzq = [i for i in range(1, xxy + 1) if i % 2 == 0] ppp = [] - nxr = None + nxr = None for pps in range(xxy): if pps == 0: @@ -139,11 +139,11 @@ class Solution: fff = False for cndt in cnd: if cndt % 2 == 1: - nxt = 0 + nxt = 0 noo = len(zzp) - 1 nee = len(zzq) else: - nxt = 1 + nxt = 1 noo = len(zzp) nee = len(zzq) - 1 @@ -164,7 +164,7 @@ class Solution: ajwi(nnss, cnt) ajwi(majs, llq) - + if cnt >= yyz: ppp.append(cndt) if cndt % 2 == 1: @@ -177,9 +177,9 @@ class Solution: break else: yyz -= cnt - + ajwi(laoq, len(ppp)) - + if not fff: return [] return ppp diff --git a/solution/3400-3499/3470.Permutations IV/README_EN.md b/solution/3400-3499/3470.Permutations IV/README_EN.md index 41f4654168597..e9907de529850 100644 --- a/solution/3400-3499/3470.Permutations IV/README_EN.md +++ b/solution/3400-3499/3470.Permutations IV/README_EN.md @@ -114,18 +114,18 @@ import heapq class Solution: def permute(self, xxy: int, yyz: int) -> List[int]: - - kasu = {} + + kasu = {} nnss = [] majs = [] ajwi = heapq.heappush laoq = [] - + zzp = [i for i in range(1, xxy + 1) if i % 2 == 1] zzq = [i for i in range(1, xxy + 1) if i % 2 == 0] ppp = [] - nxr = None + nxr = None for pps in range(xxy): if pps == 0: @@ -136,11 +136,11 @@ class Solution: fff = False for cndt in cnd: if cndt % 2 == 1: - nxt = 0 + nxt = 0 noo = len(zzp) - 1 nee = len(zzq) else: - nxt = 1 + nxt = 1 noo = len(zzp) nee = len(zzq) - 1 @@ -161,7 +161,7 @@ class Solution: ajwi(nnss, cnt) ajwi(majs, llq) - + if cnt >= yyz: ppp.append(cndt) if cndt % 2 == 1: @@ -174,9 +174,9 @@ class Solution: break else: yyz -= cnt - + ajwi(laoq, len(ppp)) - + if not fff: return [] return ppp From 202e12030d86af9943874731fba7a407091da28d Mon Sep 17 00:00:00 2001 From: Samarth Swami <70163465+samarthswami1016@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:35:30 +0530 Subject: [PATCH 05/13] Update README.md --- solution/3400-3499/3470.Permutations IV/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/solution/3400-3499/3470.Permutations IV/README.md b/solution/3400-3499/3470.Permutations IV/README.md index f530d2870c0c7..d79bd31997017 100644 --- a/solution/3400-3499/3470.Permutations IV/README.md +++ b/solution/3400-3499/3470.Permutations IV/README.md @@ -111,6 +111,7 @@ tags: #### Python3 ```python + from typing import List from math import factorial import heapq @@ -183,11 +184,13 @@ class Solution: if not fff: return [] return ppp + ``` #### Java ```java + import java.util.*; class DPHelper { @@ -345,11 +348,13 @@ class Solution { return ans; } } + ``` #### C++ ```cpp + class Solution { long long f[105]; public: @@ -390,11 +395,13 @@ public: return ans; } }; + ``` #### Go ```go + func permute(n int, k int64) []int { var f [105]int64 f[0] = 1 @@ -446,6 +453,7 @@ func permute(n int, k int64) []int { } return ans } + ``` From cb369826e65d6f36840194d8fdadb3100620295f Mon Sep 17 00:00:00 2001 From: Samarth Swami <70163465+samarthswami1016@users.noreply.github.com> Date: Tue, 11 Mar 2025 23:36:21 +0530 Subject: [PATCH 06/13] Update README_EN.md --- solution/3400-3499/3470.Permutations IV/README_EN.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/solution/3400-3499/3470.Permutations IV/README_EN.md b/solution/3400-3499/3470.Permutations IV/README_EN.md index e9907de529850..970a3101aa776 100644 --- a/solution/3400-3499/3470.Permutations IV/README_EN.md +++ b/solution/3400-3499/3470.Permutations IV/README_EN.md @@ -108,6 +108,7 @@ tags: #### Python3 ```python + from typing import List from math import factorial import heapq @@ -180,11 +181,13 @@ class Solution: if not fff: return [] return ppp + ``` #### Java ```java + import java.util.*; class DPHelper { @@ -342,11 +345,13 @@ class Solution { return ans; } } + ``` #### C++ ```cpp + class Solution { long long f[105]; public: @@ -387,11 +392,13 @@ public: return ans; } }; + ``` #### Go ```go + func permute(n int, k int64) []int { var f [105]int64 f[0] = 1 @@ -443,6 +450,7 @@ func permute(n int, k int64) []int { } return ans } + ``` From 0c9a8c921ad85fa3a0aa0cd3a260102c7caaa20a Mon Sep 17 00:00:00 2001 From: Samarth Swami Date: Sat, 5 Apr 2025 02:39:38 +0530 Subject: [PATCH 07/13] Push --- .../README.md | 167 ++++++++++++++++++ .../README_EN.md | 167 ++++++++++++++++++ .../solution.cpp | 59 +++++++ .../solution.java | 35 ++++ .../solution.py | 58 ++++++ 5 files changed, 486 insertions(+) create mode 100644 solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.cpp create mode 100644 solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.java create mode 100644 solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.py diff --git a/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README.md b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README.md index 305837bdbe0bf..1e775efb1e18d 100644 --- a/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README.md +++ b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README.md @@ -91,18 +91,185 @@ tags: ```python + +from sortedcontainers import SortedList as SL +fmin = lambda a, b: a if a < b else b +class Solution: + def minOperations(self, nums: List[int], l: int, k: int) -> int: + n = len(nums) + lt, gt = SL(), SL() + ls, gs = 0, 0 + def add(x): + nonlocal ls, gs + if not lt or x <= lt[-1]: + lt.add(x) + ls += x + else: + gt.add(x) + gs += x + def remove(x): + nonlocal ls, gs + if x <= lt[-1]: + lt.remove(x) + ls -= x + else: + gt.remove(x) + gs -= x + def adjust(): + nonlocal ls, gs + if len(lt) - len(gt) > 1: + x = lt.pop(-1) + ls -= x + gt.add(x) + gs += x + elif len(gt) - len(lt) > 0: + x = gt.pop(0) + gs -= x + lt.add(x) + ls += x + def getmed(): + return lt[-1] + cost = [0] * (n-l+1) + for i, x in enumerate(nums): + add(x) + adjust() + if i >= l: + remove(nums[i-l]) + adjust() + if i >= l-1: + med = getmed() + cur = gs - med*(len(gt)) + med*len(lt) - ls + cost[i-l+1] = cur + # print(cost) + dp = [[inf] * (k+1) for _ in range(n+1)] + dp[0][0] = 0 + for i in range(1, n+1): + for j in range(k+1): + dp[i][j] = dp[i-1][j] + if i-l >= 0 and k > 0: + dp[i][j] = fmin(dp[i][j], dp[i-l][j-1] + cost[i-l]) + + return dp[n][k] + + ``` #### Java ```java + +class Solution { + + public long minOperations(int[] nums, int x, int k) { + TreeSet set1 = new TreeSet<>((o, p) -> nums[o] == nums[p] ? o - p : nums[o] - nums[p]), set2 = new TreeSet<>((o, p) -> nums[o] == nums[p] ? o - p : nums[o] - nums[p]); + long sum[] = new long[nums.length - x + 1], left = 0, right = 0; + for (int i = 0; i < nums.length; i++) { + set2.add(i); + left += nums[set2.first()]; + right += nums[i] - nums[set2.first()]; + set1.add(set2.pollFirst()); + if (set1.size() > set2.size()) { + left -= nums[set1.last()]; + right += nums[set1.last()]; + set2.add(set1.pollLast()); + } + if (i >= x - 1) { + sum[i - x + 1] = nums[set2.first()] * (set1.size() - set2.size()) - left + right; + left -= set1.remove(i - x + 1) ? nums[i - x + 1] : 0; + right -= set2.remove(i - x + 1) ? nums[i - x + 1] : 0; + } + } + long[][] dp = new long[sum.length + x][k + 1]; + for (int i = 0; i < sum.length + x; i++) { + for (int j = 1; j <= k; j++) { + dp[i][j] = 1000000000000000000L; + } + } + for (int i = 0; i < sum.length; i++) { + for (int j = 1; j <= k; j++) { + dp[i + x][j] = Math.min(dp[i + x - 1][j], sum[i] + dp[i][j - 1]); + } + } + return dp[sum.length + x - 1][k]; + } +} + + ``` #### C++ ```cpp + +class Solution +{ +public: +#define ll long long + ll f[100003][23]; + long long minOperations(vector &a, int x, int k) + { + int n = a.size(); + for (int j = 0; j <= n; ++j) + for (int i = 0; i <= k; ++i) + f[j][i] = 1e18; + f[0][0] = 0; + multiset A, B; + ll as = 0, bs = 0; + for (int i = 0; i < n; ++i) + { + if (B.empty()) + as += a[i], A.insert(a[i]); + else if (A.empty()) + bs += a[i], B.insert(a[i]); + else if (a[i] <= *A.rbegin()) + as += a[i], A.insert(a[i]); + else + bs += a[i], B.insert(a[i]); + if (i - x >= 0) + { + if (A.find(a[i - x]) != A.end()) + { + as -= a[i - x], A.erase(A.find(a[i - x])); + } + else + { + bs -= a[i - x], B.erase(B.find(a[i - x])); + } + } + int sa = A.size(), sb = B.size(); + while (sa - sb >= 2) + { + int o = *A.rbegin(); + as -= o, bs += o; + B.insert(*A.rbegin()), A.erase(prev(A.end())); + --sa, ++sb; + } + while (sa < sb) + { + int o = *B.begin(); + bs -= o, as += o; + A.insert(*B.begin()), B.erase(B.begin()); + ++sa, --sb; + } + // 3 2 + // 3 3 + for (int j = 0; j <= k; ++j) + f[i + 1][j] = f[i][j]; + if (i >= x - 1) + { + ll Z = *A.rbegin(); + ll cost = Z * A.size() - as + bs - Z * B.size(); + for (int j = 1; j <= k; ++j) + f[i + 1][j] = min(f[i + 1][j], f[i - x + 1][j - 1] + cost); + } + } + return f[n][k]; + } +}; + + ``` #### Go diff --git a/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README_EN.md b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README_EN.md index 182675e675e99..b1357e730bd34 100644 --- a/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README_EN.md +++ b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README_EN.md @@ -86,18 +86,185 @@ tags: ```python + +from sortedcontainers import SortedList as SL +fmin = lambda a, b: a if a < b else b +class Solution: + def minOperations(self, nums: List[int], l: int, k: int) -> int: + n = len(nums) + lt, gt = SL(), SL() + ls, gs = 0, 0 + def add(x): + nonlocal ls, gs + if not lt or x <= lt[-1]: + lt.add(x) + ls += x + else: + gt.add(x) + gs += x + def remove(x): + nonlocal ls, gs + if x <= lt[-1]: + lt.remove(x) + ls -= x + else: + gt.remove(x) + gs -= x + def adjust(): + nonlocal ls, gs + if len(lt) - len(gt) > 1: + x = lt.pop(-1) + ls -= x + gt.add(x) + gs += x + elif len(gt) - len(lt) > 0: + x = gt.pop(0) + gs -= x + lt.add(x) + ls += x + def getmed(): + return lt[-1] + cost = [0] * (n-l+1) + for i, x in enumerate(nums): + add(x) + adjust() + if i >= l: + remove(nums[i-l]) + adjust() + if i >= l-1: + med = getmed() + cur = gs - med*(len(gt)) + med*len(lt) - ls + cost[i-l+1] = cur + # print(cost) + dp = [[inf] * (k+1) for _ in range(n+1)] + dp[0][0] = 0 + for i in range(1, n+1): + for j in range(k+1): + dp[i][j] = dp[i-1][j] + if i-l >= 0 and k > 0: + dp[i][j] = fmin(dp[i][j], dp[i-l][j-1] + cost[i-l]) + + return dp[n][k] + + ``` #### Java ```java + + class Solution { + + public long minOperations(int[] nums, int x, int k) { + TreeSet set1 = new TreeSet<>((o, p) -> nums[o] == nums[p] ? o - p : nums[o] - nums[p]), set2 = new TreeSet<>((o, p) -> nums[o] == nums[p] ? o - p : nums[o] - nums[p]); + long sum[] = new long[nums.length - x + 1], left = 0, right = 0; + for (int i = 0; i < nums.length; i++) { + set2.add(i); + left += nums[set2.first()]; + right += nums[i] - nums[set2.first()]; + set1.add(set2.pollFirst()); + if (set1.size() > set2.size()) { + left -= nums[set1.last()]; + right += nums[set1.last()]; + set2.add(set1.pollLast()); + } + if (i >= x - 1) { + sum[i - x + 1] = nums[set2.first()] * (set1.size() - set2.size()) - left + right; + left -= set1.remove(i - x + 1) ? nums[i - x + 1] : 0; + right -= set2.remove(i - x + 1) ? nums[i - x + 1] : 0; + } + } + long[][] dp = new long[sum.length + x][k + 1]; + for (int i = 0; i < sum.length + x; i++) { + for (int j = 1; j <= k; j++) { + dp[i][j] = 1000000000000000000L; + } + } + for (int i = 0; i < sum.length; i++) { + for (int j = 1; j <= k; j++) { + dp[i + x][j] = Math.min(dp[i + x - 1][j], sum[i] + dp[i][j - 1]); + } + } + return dp[sum.length + x - 1][k]; + } +} + + ``` #### C++ ```cpp + + class Solution +{ +public: +#define ll long long + ll f[100003][23]; + long long minOperations(vector &a, int x, int k) + { + int n = a.size(); + for (int j = 0; j <= n; ++j) + for (int i = 0; i <= k; ++i) + f[j][i] = 1e18; + f[0][0] = 0; + multiset A, B; + ll as = 0, bs = 0; + for (int i = 0; i < n; ++i) + { + if (B.empty()) + as += a[i], A.insert(a[i]); + else if (A.empty()) + bs += a[i], B.insert(a[i]); + else if (a[i] <= *A.rbegin()) + as += a[i], A.insert(a[i]); + else + bs += a[i], B.insert(a[i]); + if (i - x >= 0) + { + if (A.find(a[i - x]) != A.end()) + { + as -= a[i - x], A.erase(A.find(a[i - x])); + } + else + { + bs -= a[i - x], B.erase(B.find(a[i - x])); + } + } + int sa = A.size(), sb = B.size(); + while (sa - sb >= 2) + { + int o = *A.rbegin(); + as -= o, bs += o; + B.insert(*A.rbegin()), A.erase(prev(A.end())); + --sa, ++sb; + } + while (sa < sb) + { + int o = *B.begin(); + bs -= o, as += o; + A.insert(*B.begin()), B.erase(B.begin()); + ++sa, --sb; + } + // 3 2 + // 3 3 + for (int j = 0; j <= k; ++j) + f[i + 1][j] = f[i][j]; + if (i >= x - 1) + { + ll Z = *A.rbegin(); + ll cost = Z * A.size() - as + bs - Z * B.size(); + for (int j = 1; j <= k; ++j) + f[i + 1][j] = min(f[i + 1][j], f[i - x + 1][j - 1] + cost); + } + } + return f[n][k]; + } +}; + + ``` #### Go diff --git a/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.cpp b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.cpp new file mode 100644 index 0000000000000..683d7d50dc22b --- /dev/null +++ b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.cpp @@ -0,0 +1,59 @@ +class Solution { +public: +#define ll long long + ll f[100003][23]; + long long minOperations(vector& a, int x, int k) { + int n=a.size(); + for(int j=0; j<=n; ++j) + for(int i=0; i<=k; ++i) + f[j][i]=1e18; + f[0][0]=0; + multiset A,B; + ll as=0,bs=0; + for(int i=0; i=0) + { + if(A.find(a[i-x])!=A.end()) + { + as-=a[i-x],A.erase(A.find(a[i-x])); + } + else + { + bs-=a[i-x],B.erase(B.find(a[i-x])); + } + } + int sa=A.size(),sb=B.size(); + while(sa-sb>=2) + { + int o=*A.rbegin(); + as-=o,bs+=o; + B.insert(*A.rbegin()),A.erase(prev(A.end())); + --sa,++sb; + } + while(sa=x-1) + { + ll Z=*A.rbegin(); + ll cost=Z*A.size()-as+bs-Z*B.size(); + for(int j=1; j<=k; ++j) + f[i+1][j]=min(f[i+1][j],f[i-x+1][j-1]+cost); + } + } + return f[n][k]; + } +}; \ No newline at end of file diff --git a/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.java b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.java new file mode 100644 index 0000000000000..8fdc4db56f2cb --- /dev/null +++ b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.java @@ -0,0 +1,35 @@ +class Solution { + + public long minOperations(int[] nums, int x, int k) { + TreeSet set1 = new TreeSet<>((o, p) -> nums[o] == nums[p] ? o - p : nums[o] - nums[p]), set2 = new TreeSet<>((o, p) -> nums[o] == nums[p] ? o - p : nums[o] - nums[p]); + long sum[] = new long[nums.length - x + 1], left = 0, right = 0; + for (int i = 0; i < nums.length; i++) { + set2.add(i); + left += nums[set2.first()]; + right += nums[i] - nums[set2.first()]; + set1.add(set2.pollFirst()); + if (set1.size() > set2.size()) { + left -= nums[set1.last()]; + right += nums[set1.last()]; + set2.add(set1.pollLast()); + } + if (i >= x - 1) { + sum[i - x + 1] = nums[set2.first()] * (set1.size() - set2.size()) - left + right; + left -= set1.remove(i - x + 1) ? nums[i - x + 1] : 0; + right -= set2.remove(i - x + 1) ? nums[i - x + 1] : 0; + } + } + long[][] dp = new long[sum.length + x][k + 1]; + for (int i = 0; i < sum.length + x; i++) { + for (int j = 1; j <= k; j++) { + dp[i][j] = 1000000000000000000L; + } + } + for (int i = 0; i < sum.length; i++) { + for (int j = 1; j <= k; j++) { + dp[i + x][j] = Math.min(dp[i + x - 1][j], sum[i] + dp[i][j - 1]); + } + } + return dp[sum.length + x - 1][k]; + } +} \ No newline at end of file diff --git a/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.py b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.py new file mode 100644 index 0000000000000..491924f6ea47c --- /dev/null +++ b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/solution.py @@ -0,0 +1,58 @@ +from sortedcontainers import SortedList as SL +fmin = lambda a, b: a if a < b else b +class Solution: + def minOperations(self, nums: List[int], l: int, k: int) -> int: + n = len(nums) + lt, gt = SL(), SL() + ls, gs = 0, 0 + def add(x): + nonlocal ls, gs + if not lt or x <= lt[-1]: + lt.add(x) + ls += x + else: + gt.add(x) + gs += x + def remove(x): + nonlocal ls, gs + if x <= lt[-1]: + lt.remove(x) + ls -= x + else: + gt.remove(x) + gs -= x + def adjust(): + nonlocal ls, gs + if len(lt) - len(gt) > 1: + x = lt.pop(-1) + ls -= x + gt.add(x) + gs += x + elif len(gt) - len(lt) > 0: + x = gt.pop(0) + gs -= x + lt.add(x) + ls += x + def getmed(): + return lt[-1] + cost = [0] * (n-l+1) + for i, x in enumerate(nums): + add(x) + adjust() + if i >= l: + remove(nums[i-l]) + adjust() + if i >= l-1: + med = getmed() + cur = gs - med*(len(gt)) + med*len(lt) - ls + cost[i-l+1] = cur + # print(cost) + dp = [[inf] * (k+1) for _ in range(n+1)] + dp[0][0] = 0 + for i in range(1, n+1): + for j in range(k+1): + dp[i][j] = dp[i-1][j] + if i-l >= 0 and k > 0: + dp[i][j] = fmin(dp[i][j], dp[i-l][j-1] + cost[i-l]) + + return dp[n][k] \ No newline at end of file From 897d9ef905fc88bda303374df9712c4a3e564026 Mon Sep 17 00:00:00 2001 From: samarthswami1016 <70163465+samarthswami1016@users.noreply.github.com> Date: Fri, 4 Apr 2025 22:09:49 +0000 Subject: [PATCH 08/13] style: format code and docs with prettier --- .../README_EN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README_EN.md b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README_EN.md index b1357e730bd34..544b5e0b09689 100644 --- a/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README_EN.md +++ b/solution/3500-3599/3505.Minimum Operations to Make Elements Within K Subarrays Equal/README_EN.md @@ -146,7 +146,7 @@ class Solution: return dp[n][k] - + ``` #### Java From 8c56e29c53cc8741aba84226db3110e10849fac8 Mon Sep 17 00:00:00 2001 From: Samarth Swami Date: Tue, 8 Apr 2025 13:03:41 +0530 Subject: [PATCH 09/13] feat: add solutions to lc problem: No.3500 --- .../README.md | 149 ++++++++++++++++++ .../README_EN.md | 149 ++++++++++++++++++ .../solution.cpp | 24 +++ .../solution.go | 20 +++ .../solution.java | 44 ++++++ .../solution.py | 57 +++++++ 6 files changed, 443 insertions(+) create mode 100644 solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.cpp create mode 100644 solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.go create mode 100644 solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.java create mode 100644 solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.py diff --git a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README.md b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README.md index 846de3bc27c55..cc1192c2ff7dc 100644 --- a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README.md +++ b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README.md @@ -93,24 +93,173 @@ tags: ```python +class Solution: + def minimumCost(self, nums: List[int], cost: List[int], k: int) -> int: + n = len(nums) + sumN = [0] * (n + 1) + sumC = [0] * (n + 1) + + for i in range(1, n + 1): + sumN[i] = sumN[i - 1] + nums[i - 1] + sumC[i] = sumC[i - 1] + cost[i - 1] + + prevDp = [sys.maxsize] * (n + 1) + prevDp[0] = 0 + + minCost = sys.maxsize + + for m in range(1, n + 1): + currentDp = [sys.maxsize] * (n + 1) + queue = [] + + for r in range(m, n + 1): + l = r - 1 + if l >= m - 1: + x = sumC[l] + y = prevDp[l] + + while len(queue) >= 2: + x1, y1 = queue[-2][0], queue[-2][1] + x2, y2 = queue[-1][0], queue[-1][1] + if (x2 - x1) * (y - y2) <= (x - x2) * (y2 - y1): + queue.pop() + else: + break + queue.append((x, y, l)) + + a = -(sumN[r] + k * m) + + while len(queue) >= 2: + x1, y1 = queue[0][0], queue[0][1] + x2, y2 = queue[1][0], queue[1][1] + if a * x1 + y1 >= a * x2 + y2: + queue.pop(0) + else: + break + + if queue: + x, y = queue[0][0], queue[0][1] + best = a * x + y + currentCost = (sumN[r] + k * m) * sumC[r] + currentCost += best + if currentCost < currentDp[r]: + currentDp[r] = currentCost + + if currentDp[n] < minCost: + minCost = currentDp[n] + prevDp = currentDp + + return minCost + ``` #### Java ```java +class Solution { + public long minimumCost(int[] nums, int[] cost, int k) { + int n = nums.length; + long[] prefixNums = new long[n]; + long[] prefixCosts = new long[n]; + prefixNums[0] = nums[0]; + for (int i = 1; i < n; i++) { + prefixNums[i] = prefixNums[i - 1] + nums[i]; + } + + prefixCosts[0] = cost[0]; + for (int i = 1; i < n; i++) { + prefixCosts[i] = prefixCosts[i - 1] + cost[i]; + } + + Long[][] dp = new Long[n][n]; + long ans = solve(0, 0, k, prefixNums, prefixCosts, dp); + return ans; + } + + public long solve(int start, int end, int k, long[] prefixNums, long[] prefixCosts, Long[][] dp) { + int n = prefixNums.length; + if (end == n) { + if (start == n) return 0; + return Long.MAX_VALUE; + } + + if (dp[start][end] != null) return dp[start][end]; + + long currentNumsSum = prefixNums[end], currentCostSum = prefixCosts[n - 1]; + + if (start != 0){ + currentNumsSum = prefixNums[end] - prefixNums[start - 1]; + currentCostSum = prefixCosts[n - 1] - prefixCosts[start - 1]; + } + + long currentSubarrayCost = (currentNumsSum + k) * currentCostSum; + + long costIfCutHere = currentSubarrayCost + solve(end + 1, end + 1, k, prefixNums, prefixCosts, dp); + long costIfExtend = solve(start, end + 1, k, prefixNums, prefixCosts, dp); + + return dp[start][end] = Math.min(costIfCutHere, costIfExtend); + } +} + ``` #### C++ ```cpp +class Solution { + public: + long long minimumCost(vector& nums, vector& cost, int K) { + int n = nums.size(); + + long long sn[n + 1], sc[n + 1]; + sn[0] = sc[0] = 0; + for (int i = 1; i <= n; i++) { + sn[i] = sn[i - 1] + nums[i - 1]; + sc[i] = sc[i - 1] + cost[i - 1]; + } + + const long long INF = 1e18; + long long f[n + 1]; + for (int i = 0; i <= n; i++) f[i] = INF; + f[0] = 0; + for (int i = 1; i <= n; i++) for (int j = 0; j < i; j++) { + long long t = sn[i] * (sc[i] - sc[j]) + K * (sc[n] - sc[j]); + f[i] = min(f[i], f[j] + t); + } + + return f[n]; + } + }; + ``` #### Go ```go +func minimumCost(a []int, b []int, k int) int64 { + n := len(a) + dp := make([]int, n + 1) + for i := range n { + dp[i] = math.MaxInt / 4 + } + prea := make([]int, n + 1) + preb := make([]int, n + 1) + for i := range n { + prea[i + 1] = prea[i] + a[i] + preb[i + 1] = preb[i] + b[i] + } + for i := n - 1; i >= 0; i-- { + for j := i; j < n; j++ { + tot := (preb[j + 1] - preb[i]) * (prea[j + 1] - prea[0]) + (preb[n] - preb[i]) * k + dp[i] = min(dp[i], tot + dp[j + 1]) + } + } + return int64(dp[0]) +} + ``` diff --git a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README_EN.md b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README_EN.md index 002c51ac750f1..a22e268029b4c 100644 --- a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README_EN.md +++ b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README_EN.md @@ -88,24 +88,173 @@ The minimum total cost possible can be achieved by dividing nums in ```python +class Solution: + def minimumCost(self, nums: List[int], cost: List[int], k: int) -> int: + n = len(nums) + sumN = [0] * (n + 1) + sumC = [0] * (n + 1) + + for i in range(1, n + 1): + sumN[i] = sumN[i - 1] + nums[i - 1] + sumC[i] = sumC[i - 1] + cost[i - 1] + + prevDp = [sys.maxsize] * (n + 1) + prevDp[0] = 0 + + minCost = sys.maxsize + + for m in range(1, n + 1): + currentDp = [sys.maxsize] * (n + 1) + queue = [] + + for r in range(m, n + 1): + l = r - 1 + if l >= m - 1: + x = sumC[l] + y = prevDp[l] + + while len(queue) >= 2: + x1, y1 = queue[-2][0], queue[-2][1] + x2, y2 = queue[-1][0], queue[-1][1] + if (x2 - x1) * (y - y2) <= (x - x2) * (y2 - y1): + queue.pop() + else: + break + queue.append((x, y, l)) + + a = -(sumN[r] + k * m) + + while len(queue) >= 2: + x1, y1 = queue[0][0], queue[0][1] + x2, y2 = queue[1][0], queue[1][1] + if a * x1 + y1 >= a * x2 + y2: + queue.pop(0) + else: + break + + if queue: + x, y = queue[0][0], queue[0][1] + best = a * x + y + currentCost = (sumN[r] + k * m) * sumC[r] + currentCost += best + if currentCost < currentDp[r]: + currentDp[r] = currentCost + + if currentDp[n] < minCost: + minCost = currentDp[n] + prevDp = currentDp + + return minCost + ``` #### Java ```java +class Solution { + public long minimumCost(int[] nums, int[] cost, int k) { + int n = nums.length; + long[] prefixNums = new long[n]; + long[] prefixCosts = new long[n]; + prefixNums[0] = nums[0]; + for (int i = 1; i < n; i++) { + prefixNums[i] = prefixNums[i - 1] + nums[i]; + } + + prefixCosts[0] = cost[0]; + for (int i = 1; i < n; i++) { + prefixCosts[i] = prefixCosts[i - 1] + cost[i]; + } + + Long[][] dp = new Long[n][n]; + long ans = solve(0, 0, k, prefixNums, prefixCosts, dp); + return ans; + } + + public long solve(int start, int end, int k, long[] prefixNums, long[] prefixCosts, Long[][] dp) { + int n = prefixNums.length; + if (end == n) { + if (start == n) return 0; + return Long.MAX_VALUE; + } + + if (dp[start][end] != null) return dp[start][end]; + + long currentNumsSum = prefixNums[end], currentCostSum = prefixCosts[n - 1]; + + if (start != 0){ + currentNumsSum = prefixNums[end] - prefixNums[start - 1]; + currentCostSum = prefixCosts[n - 1] - prefixCosts[start - 1]; + } + + long currentSubarrayCost = (currentNumsSum + k) * currentCostSum; + + long costIfCutHere = currentSubarrayCost + solve(end + 1, end + 1, k, prefixNums, prefixCosts, dp); + long costIfExtend = solve(start, end + 1, k, prefixNums, prefixCosts, dp); + + return dp[start][end] = Math.min(costIfCutHere, costIfExtend); + } +} + ``` #### C++ ```cpp +class Solution { + public: + long long minimumCost(vector& nums, vector& cost, int K) { + int n = nums.size(); + + long long sn[n + 1], sc[n + 1]; + sn[0] = sc[0] = 0; + for (int i = 1; i <= n; i++) { + sn[i] = sn[i - 1] + nums[i - 1]; + sc[i] = sc[i - 1] + cost[i - 1]; + } + + const long long INF = 1e18; + long long f[n + 1]; + for (int i = 0; i <= n; i++) f[i] = INF; + f[0] = 0; + for (int i = 1; i <= n; i++) for (int j = 0; j < i; j++) { + long long t = sn[i] * (sc[i] - sc[j]) + K * (sc[n] - sc[j]); + f[i] = min(f[i], f[j] + t); + } + + return f[n]; + } + }; + ``` #### Go ```go +func minimumCost(a []int, b []int, k int) int64 { + n := len(a) + dp := make([]int, n + 1) + for i := range n { + dp[i] = math.MaxInt / 4 + } + prea := make([]int, n + 1) + preb := make([]int, n + 1) + for i := range n { + prea[i + 1] = prea[i] + a[i] + preb[i + 1] = preb[i] + b[i] + } + for i := n - 1; i >= 0; i-- { + for j := i; j < n; j++ { + tot := (preb[j + 1] - preb[i]) * (prea[j + 1] - prea[0]) + (preb[n] - preb[i]) * k + dp[i] = min(dp[i], tot + dp[j + 1]) + } + } + return int64(dp[0]) +} + ``` diff --git a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.cpp b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.cpp new file mode 100644 index 0000000000000..f087b20b76627 --- /dev/null +++ b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.cpp @@ -0,0 +1,24 @@ +class Solution { + public: + long long minimumCost(vector& nums, vector& cost, int K) { + int n = nums.size(); + + long long sn[n + 1], sc[n + 1]; + sn[0] = sc[0] = 0; + for (int i = 1; i <= n; i++) { + sn[i] = sn[i - 1] + nums[i - 1]; + sc[i] = sc[i - 1] + cost[i - 1]; + } + + const long long INF = 1e18; + long long f[n + 1]; + for (int i = 0; i <= n; i++) f[i] = INF; + f[0] = 0; + for (int i = 1; i <= n; i++) for (int j = 0; j < i; j++) { + long long t = sn[i] * (sc[i] - sc[j]) + K * (sc[n] - sc[j]); + f[i] = min(f[i], f[j] + t); + } + + return f[n]; + } + }; \ No newline at end of file diff --git a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.go b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.go new file mode 100644 index 0000000000000..811d09609e336 --- /dev/null +++ b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.go @@ -0,0 +1,20 @@ +func minimumCost(a []int, b []int, k int) int64 { + n := len(a) + dp := make([]int, n + 1) + for i := range n { + dp[i] = math.MaxInt / 4 + } + prea := make([]int, n + 1) + preb := make([]int, n + 1) + for i := range n { + prea[i + 1] = prea[i] + a[i] + preb[i + 1] = preb[i] + b[i] + } + for i := n - 1; i >= 0; i-- { + for j := i; j < n; j++ { + tot := (preb[j + 1] - preb[i]) * (prea[j + 1] - prea[0]) + (preb[n] - preb[i]) * k + dp[i] = min(dp[i], tot + dp[j + 1]) + } + } + return int64(dp[0]) +} \ No newline at end of file diff --git a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.java b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.java new file mode 100644 index 0000000000000..91244e8f2e551 --- /dev/null +++ b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.java @@ -0,0 +1,44 @@ +class Solution { + public long minimumCost(int[] nums, int[] cost, int k) { + int n = nums.length; + long[] prefixNums = new long[n]; + long[] prefixCosts = new long[n]; + prefixNums[0] = nums[0]; + for (int i = 1; i < n; i++) { + prefixNums[i] = prefixNums[i - 1] + nums[i]; + } + + prefixCosts[0] = cost[0]; + for (int i = 1; i < n; i++) { + prefixCosts[i] = prefixCosts[i - 1] + cost[i]; + } + + Long[][] dp = new Long[n][n]; + long ans = solve(0, 0, k, prefixNums, prefixCosts, dp); + return ans; + } + + public long solve(int start, int end, int k, long[] prefixNums, long[] prefixCosts, Long[][] dp) { + int n = prefixNums.length; + if (end == n) { + if (start == n) return 0; + return Long.MAX_VALUE; + } + + if (dp[start][end] != null) return dp[start][end]; + + long currentNumsSum = prefixNums[end], currentCostSum = prefixCosts[n - 1]; + + if (start != 0){ + currentNumsSum = prefixNums[end] - prefixNums[start - 1]; + currentCostSum = prefixCosts[n - 1] - prefixCosts[start - 1]; + } + + long currentSubarrayCost = (currentNumsSum + k) * currentCostSum; + + long costIfCutHere = currentSubarrayCost + solve(end + 1, end + 1, k, prefixNums, prefixCosts, dp); + long costIfExtend = solve(start, end + 1, k, prefixNums, prefixCosts, dp); + + return dp[start][end] = Math.min(costIfCutHere, costIfExtend); + } +} diff --git a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.py b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.py new file mode 100644 index 0000000000000..fa90d3facfa1c --- /dev/null +++ b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/solution.py @@ -0,0 +1,57 @@ +class Solution: + def minimumCost(self, nums: List[int], cost: List[int], k: int) -> int: + n = len(nums) + sumN = [0] * (n + 1) + sumC = [0] * (n + 1) + + for i in range(1, n + 1): + sumN[i] = sumN[i - 1] + nums[i - 1] + sumC[i] = sumC[i - 1] + cost[i - 1] + + prevDp = [sys.maxsize] * (n + 1) + prevDp[0] = 0 + + minCost = sys.maxsize + + for m in range(1, n + 1): + currentDp = [sys.maxsize] * (n + 1) + queue = [] + + for r in range(m, n + 1): + l = r - 1 + if l >= m - 1: + x = sumC[l] + y = prevDp[l] + + while len(queue) >= 2: + x1, y1 = queue[-2][0], queue[-2][1] + x2, y2 = queue[-1][0], queue[-1][1] + if (x2 - x1) * (y - y2) <= (x - x2) * (y2 - y1): + queue.pop() + else: + break + queue.append((x, y, l)) + + a = -(sumN[r] + k * m) + + while len(queue) >= 2: + x1, y1 = queue[0][0], queue[0][1] + x2, y2 = queue[1][0], queue[1][1] + if a * x1 + y1 >= a * x2 + y2: + queue.pop(0) + else: + break + + if queue: + x, y = queue[0][0], queue[0][1] + best = a * x + y + currentCost = (sumN[r] + k * m) * sumC[r] + currentCost += best + if currentCost < currentDp[r]: + currentDp[r] = currentCost + + if currentDp[n] < minCost: + minCost = currentDp[n] + prevDp = currentDp + + return minCost \ No newline at end of file From 09668b7135c048c3a1c966d1d5852e1d711f08af Mon Sep 17 00:00:00 2001 From: samarthswami1016 <70163465+samarthswami1016@users.noreply.github.com> Date: Tue, 8 Apr 2025 08:21:53 +0000 Subject: [PATCH 10/13] style: format code and docs with prettier --- .../README.md | 12 ++++++------ .../README_EN.md | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README.md b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README.md index cc1192c2ff7dc..34ffae134cadb 100644 --- a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README.md +++ b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README.md @@ -98,7 +98,7 @@ class Solution: n = len(nums) sumN = [0] * (n + 1) sumC = [0] * (n + 1) - + for i in range(1, n + 1): sumN[i] = sumN[i - 1] + nums[i - 1] sumC[i] = sumC[i - 1] + cost[i - 1] @@ -183,7 +183,7 @@ class Solution { if (start == n) return 0; return Long.MAX_VALUE; } - + if (dp[start][end] != null) return dp[start][end]; long currentNumsSum = prefixNums[end], currentCostSum = prefixCosts[n - 1]; @@ -212,14 +212,14 @@ class Solution { public: long long minimumCost(vector& nums, vector& cost, int K) { int n = nums.size(); - + long long sn[n + 1], sc[n + 1]; sn[0] = sc[0] = 0; for (int i = 1; i <= n; i++) { sn[i] = sn[i - 1] + nums[i - 1]; sc[i] = sc[i - 1] + cost[i - 1]; } - + const long long INF = 1e18; long long f[n + 1]; for (int i = 0; i <= n; i++) f[i] = INF; @@ -228,11 +228,11 @@ class Solution { long long t = sn[i] * (sc[i] - sc[j]) + K * (sc[n] - sc[j]); f[i] = min(f[i], f[j] + t); } - + return f[n]; } }; - + ``` #### Go diff --git a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README_EN.md b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README_EN.md index a22e268029b4c..451e626574669 100644 --- a/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README_EN.md +++ b/solution/3500-3599/3500.Minimum Cost to Divide Array Into Subarrays/README_EN.md @@ -93,7 +93,7 @@ class Solution: n = len(nums) sumN = [0] * (n + 1) sumC = [0] * (n + 1) - + for i in range(1, n + 1): sumN[i] = sumN[i - 1] + nums[i - 1] sumC[i] = sumC[i - 1] + cost[i - 1] @@ -178,7 +178,7 @@ class Solution { if (start == n) return 0; return Long.MAX_VALUE; } - + if (dp[start][end] != null) return dp[start][end]; long currentNumsSum = prefixNums[end], currentCostSum = prefixCosts[n - 1]; @@ -207,14 +207,14 @@ class Solution { public: long long minimumCost(vector& nums, vector& cost, int K) { int n = nums.size(); - + long long sn[n + 1], sc[n + 1]; sn[0] = sc[0] = 0; for (int i = 1; i <= n; i++) { sn[i] = sn[i - 1] + nums[i - 1]; sc[i] = sc[i - 1] + cost[i - 1]; } - + const long long INF = 1e18; long long f[n + 1]; for (int i = 0; i <= n; i++) f[i] = INF; @@ -223,7 +223,7 @@ class Solution { long long t = sn[i] * (sc[i] - sc[j]) + K * (sc[n] - sc[j]); f[i] = min(f[i], f[j] + t); } - + return f[n]; } }; From 3b925b4bd25ef47a4239bbe1415420c318453764 Mon Sep 17 00:00:00 2001 From: Samarth Swami Date: Sun, 20 Jul 2025 17:15:34 +0530 Subject: [PATCH 11/13] feat: add solutions to lc problem: No.1948 --- .../README.md | 227 ++++++++++++++++++ .../README_EN.md | 227 ++++++++++++++++++ .../solution.cpp | 61 +++++ .../solution.go | 56 +++++ .../solution.java | 63 +++++ .../solution.js | 50 ++++ .../solution.py | 42 ++++ 7 files changed, 726 insertions(+) create mode 100644 solution/1900-1999/1948.Delete Duplicate Folders in System/solution.cpp create mode 100644 solution/1900-1999/1948.Delete Duplicate Folders in System/solution.go create mode 100644 solution/1900-1999/1948.Delete Duplicate Folders in System/solution.java create mode 100644 solution/1900-1999/1948.Delete Duplicate Folders in System/solution.js create mode 100644 solution/1900-1999/1948.Delete Duplicate Folders in System/solution.py diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md b/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md index d3255436fb79c..a42a97fe21ade 100644 --- a/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md @@ -130,24 +130,251 @@ tags: ```python +class Trie: + serial: str = "" + children: dict + + def __init__(self): + self.children = dict() + + +class Solution: + def deleteDuplicateFolder(self, paths: List[List[str]]) -> List[List[str]]: + root = Trie() + for path in paths: + cur = root + for node in path: + if node not in cur.children: + cur.children[node] = Trie() + cur = cur.children[node] + freq = Counter() + def construct(node: Trie) -> None: + if not node.children: + return + v = list() + for folder, child in node.children.items(): + construct(child) + v.append(folder + "(" + child.serial + ")") + v.sort() + node.serial = "".join(v) + freq[node.serial] += 1 + construct(root) + ans = list() + path = list() + def operate(node: Trie) -> None: + if freq[node.serial] > 1: + return + if path: + ans.append(path[:]) + for folder, child in node.children.items(): + path.append(folder) + operate(child) + path.pop() + operate(root) + return ans + ``` #### Java ```java +class Solution { + + class Trie { + + String serial; + Map children = new HashMap<>(); + } + + public List> deleteDuplicateFolder(List> paths) { + Trie root = new Trie(); + for (List path : paths) { + Trie cur = root; + for (String node : path) { + cur.children.putIfAbsent(node, new Trie()); + cur = cur.children.get(node); + } + } + + Map freq = new HashMap<>(); + construct(root, freq); + List> ans = new ArrayList<>(); + List path = new ArrayList<>(); + operate(root, freq, path, ans); + return ans; + } + + private void construct(Trie node, Map freq) { + if (node.children.isEmpty()) return; + + List v = new ArrayList<>(); + for (Map.Entry entry : node.children.entrySet()) { + construct(entry.getValue(), freq); + v.add(entry.getKey() + "(" + entry.getValue().serial + ")"); + } + + Collections.sort(v); + StringBuilder sb = new StringBuilder(); + for (String s : v) { + sb.append(s); + } + node.serial = sb.toString(); + freq.put(node.serial, freq.getOrDefault(node.serial, 0) + 1); + } + + private void operate( + Trie node, + Map freq, + List path, + List> ans + ) { + if (freq.getOrDefault(node.serial, 0) > 1) return; + + if (!path.isEmpty()) { + ans.add(new ArrayList<>(path)); + } + + for (Map.Entry entry : node.children.entrySet()) { + path.add(entry.getKey()); + operate(entry.getValue(), freq, path, ans); + path.remove(path.size() - 1); + } + } +} + ``` #### C++ ```cpp +struct Trie { + string serial; + unordered_map children; +}; + +class Solution { +public: + vector> deleteDuplicateFolder( + vector>& paths) { + Trie* root = new Trie(); + + for (const vector& path : paths) { + Trie* cur = root; + for (const string& node : path) { + if (!cur->children.count(node)) { + cur->children[node] = new Trie(); + } + cur = cur->children[node]; + } + } + unordered_map freq; + function construct = [&](Trie* node) { + if (node->children.empty()) { + return; + } + + vector v; + for (const auto& [folder, child] : node->children) { + construct(child); + v.push_back(folder + "(" + child->serial + ")"); + } + sort(v.begin(), v.end()); + for (string& s : v) { + node->serial += move(s); + } + ++freq[node->serial]; + }; + + construct(root); + + vector> ans; + vector path; + + function operate = [&](Trie* node) { + if (freq[node->serial] > 1) { + return; + } + if (!path.empty()) { + ans.push_back(path); + } + for (const auto& [folder, child] : node->children) { + path.push_back(folder); + operate(child); + path.pop_back(); + } + }; + + operate(root); + return ans; + } +}; + ``` #### Go ```go +type Trie struct { + serial string + children map[string]*Trie +} + +func deleteDuplicateFolder(paths [][]string) [][]string { + root := &Trie{children: make(map[string]*Trie)} + for _, path := range paths { + cur := root + for _, node := range path { + if _, ok := cur.children[node]; !ok { + cur.children[node] = &Trie{children: make(map[string]*Trie)} + } + cur = cur.children[node] + } + } + + freq := make(map[string]int) + var construct func(*Trie) + construct = func(node *Trie) { + if len(node.children) == 0 { + return + } + v := make([]string, 0, len(node.children)) + for folder, child := range node.children { + construct(child) + v = append(v, folder+"("+child.serial+")") + } + sort.Strings(v) + node.serial = strings.Join(v, "") + freq[node.serial]++ + } + construct(root) + + ans := make([][]string, 0) + path := make([]string, 0) + var operate func(*Trie) + operate = func(node *Trie) { + if freq[node.serial] > 1 { + return + } + if len(path) > 0 { + tmp := make([]string, len(path)) + copy(tmp, path) + ans = append(ans, tmp) + } + for folder, child := range node.children { + path = append(path, folder) + operate(child) + path = path[:len(path)-1] + } + } + operate(root) + + return ans +} + + ``` diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md b/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md index 01fa7d10a03c7..24574d0aef1f7 100644 --- a/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md @@ -109,24 +109,251 @@ Note that the returned array can be in a different order as the order does not m ```python +class Trie: + serial: str = "" + children: dict + + def __init__(self): + self.children = dict() + + +class Solution: + def deleteDuplicateFolder(self, paths: List[List[str]]) -> List[List[str]]: + root = Trie() + for path in paths: + cur = root + for node in path: + if node not in cur.children: + cur.children[node] = Trie() + cur = cur.children[node] + freq = Counter() + def construct(node: Trie) -> None: + if not node.children: + return + v = list() + for folder, child in node.children.items(): + construct(child) + v.append(folder + "(" + child.serial + ")") + v.sort() + node.serial = "".join(v) + freq[node.serial] += 1 + construct(root) + ans = list() + path = list() + def operate(node: Trie) -> None: + if freq[node.serial] > 1: + return + if path: + ans.append(path[:]) + for folder, child in node.children.items(): + path.append(folder) + operate(child) + path.pop() + operate(root) + return ans + ``` #### Java ```java +class Solution { + + class Trie { + + String serial; + Map children = new HashMap<>(); + } + + public List> deleteDuplicateFolder(List> paths) { + Trie root = new Trie(); + for (List path : paths) { + Trie cur = root; + for (String node : path) { + cur.children.putIfAbsent(node, new Trie()); + cur = cur.children.get(node); + } + } + + Map freq = new HashMap<>(); + construct(root, freq); + List> ans = new ArrayList<>(); + List path = new ArrayList<>(); + operate(root, freq, path, ans); + return ans; + } + + private void construct(Trie node, Map freq) { + if (node.children.isEmpty()) return; + + List v = new ArrayList<>(); + for (Map.Entry entry : node.children.entrySet()) { + construct(entry.getValue(), freq); + v.add(entry.getKey() + "(" + entry.getValue().serial + ")"); + } + + Collections.sort(v); + StringBuilder sb = new StringBuilder(); + for (String s : v) { + sb.append(s); + } + node.serial = sb.toString(); + freq.put(node.serial, freq.getOrDefault(node.serial, 0) + 1); + } + + private void operate( + Trie node, + Map freq, + List path, + List> ans + ) { + if (freq.getOrDefault(node.serial, 0) > 1) return; + + if (!path.isEmpty()) { + ans.add(new ArrayList<>(path)); + } + + for (Map.Entry entry : node.children.entrySet()) { + path.add(entry.getKey()); + operate(entry.getValue(), freq, path, ans); + path.remove(path.size() - 1); + } + } +} + ``` #### C++ ```cpp +struct Trie { + string serial; + unordered_map children; +}; + +class Solution { +public: + vector> deleteDuplicateFolder( + vector>& paths) { + Trie* root = new Trie(); + + for (const vector& path : paths) { + Trie* cur = root; + for (const string& node : path) { + if (!cur->children.count(node)) { + cur->children[node] = new Trie(); + } + cur = cur->children[node]; + } + } + unordered_map freq; + function construct = [&](Trie* node) { + if (node->children.empty()) { + return; + } + + vector v; + for (const auto& [folder, child] : node->children) { + construct(child); + v.push_back(folder + "(" + child->serial + ")"); + } + sort(v.begin(), v.end()); + for (string& s : v) { + node->serial += move(s); + } + ++freq[node->serial]; + }; + + construct(root); + + vector> ans; + vector path; + + function operate = [&](Trie* node) { + if (freq[node->serial] > 1) { + return; + } + if (!path.empty()) { + ans.push_back(path); + } + for (const auto& [folder, child] : node->children) { + path.push_back(folder); + operate(child); + path.pop_back(); + } + }; + + operate(root); + return ans; + } +}; + ``` #### Go ```go +type Trie struct { + serial string + children map[string]*Trie +} + +func deleteDuplicateFolder(paths [][]string) [][]string { + root := &Trie{children: make(map[string]*Trie)} + for _, path := range paths { + cur := root + for _, node := range path { + if _, ok := cur.children[node]; !ok { + cur.children[node] = &Trie{children: make(map[string]*Trie)} + } + cur = cur.children[node] + } + } + + freq := make(map[string]int) + var construct func(*Trie) + construct = func(node *Trie) { + if len(node.children) == 0 { + return + } + v := make([]string, 0, len(node.children)) + for folder, child := range node.children { + construct(child) + v = append(v, folder+"("+child.serial+")") + } + sort.Strings(v) + node.serial = strings.Join(v, "") + freq[node.serial]++ + } + construct(root) + + ans := make([][]string, 0) + path := make([]string, 0) + var operate func(*Trie) + operate = func(node *Trie) { + if freq[node.serial] > 1 { + return + } + if len(path) > 0 { + tmp := make([]string, len(path)) + copy(tmp, path) + ans = append(ans, tmp) + } + for folder, child := range node.children { + path = append(path, folder) + operate(child) + path = path[:len(path)-1] + } + } + operate(root) + + return ans +} + + ``` diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.cpp b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.cpp new file mode 100644 index 0000000000000..cf6d5ca6ad4b8 --- /dev/null +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.cpp @@ -0,0 +1,61 @@ +struct Trie { + string serial; + unordered_map children; +}; + +class Solution { +public: + vector> deleteDuplicateFolder( + vector>& paths) { + Trie* root = new Trie(); + + for (const vector& path : paths) { + Trie* cur = root; + for (const string& node : path) { + if (!cur->children.count(node)) { + cur->children[node] = new Trie(); + } + cur = cur->children[node]; + } + } + unordered_map freq; + function construct = [&](Trie* node) { + if (node->children.empty()) { + return; + } + + vector v; + for (const auto& [folder, child] : node->children) { + construct(child); + v.push_back(folder + "(" + child->serial + ")"); + } + sort(v.begin(), v.end()); + for (string& s : v) { + node->serial += move(s); + } + ++freq[node->serial]; + }; + + construct(root); + + vector> ans; + vector path; + + function operate = [&](Trie* node) { + if (freq[node->serial] > 1) { + return; + } + if (!path.empty()) { + ans.push_back(path); + } + for (const auto& [folder, child] : node->children) { + path.push_back(folder); + operate(child); + path.pop_back(); + } + }; + + operate(root); + return ans; + } +}; \ No newline at end of file diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.go b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.go new file mode 100644 index 0000000000000..7feb000eb38ed --- /dev/null +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.go @@ -0,0 +1,56 @@ +type Trie struct { + serial string + children map[string]*Trie +} + +func deleteDuplicateFolder(paths [][]string) [][]string { + root := &Trie{children: make(map[string]*Trie)} + for _, path := range paths { + cur := root + for _, node := range path { + if _, ok := cur.children[node]; !ok { + cur.children[node] = &Trie{children: make(map[string]*Trie)} + } + cur = cur.children[node] + } + } + + freq := make(map[string]int) + var construct func(*Trie) + construct = func(node *Trie) { + if len(node.children) == 0 { + return + } + v := make([]string, 0, len(node.children)) + for folder, child := range node.children { + construct(child) + v = append(v, folder+"("+child.serial+")") + } + sort.Strings(v) + node.serial = strings.Join(v, "") + freq[node.serial]++ + } + construct(root) + + ans := make([][]string, 0) + path := make([]string, 0) + var operate func(*Trie) + operate = func(node *Trie) { + if freq[node.serial] > 1 { + return + } + if len(path) > 0 { + tmp := make([]string, len(path)) + copy(tmp, path) + ans = append(ans, tmp) + } + for folder, child := range node.children { + path = append(path, folder) + operate(child) + path = path[:len(path)-1] + } + } + operate(root) + + return ans +} diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.java b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.java new file mode 100644 index 0000000000000..5bed3ae5d3b4b --- /dev/null +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.java @@ -0,0 +1,63 @@ +class Solution { + + class Trie { + + String serial; + Map children = new HashMap<>(); + } + + public List> deleteDuplicateFolder(List> paths) { + Trie root = new Trie(); + for (List path : paths) { + Trie cur = root; + for (String node : path) { + cur.children.putIfAbsent(node, new Trie()); + cur = cur.children.get(node); + } + } + + Map freq = new HashMap<>(); + construct(root, freq); + List> ans = new ArrayList<>(); + List path = new ArrayList<>(); + operate(root, freq, path, ans); + return ans; + } + + private void construct(Trie node, Map freq) { + if (node.children.isEmpty()) return; + + List v = new ArrayList<>(); + for (Map.Entry entry : node.children.entrySet()) { + construct(entry.getValue(), freq); + v.add(entry.getKey() + "(" + entry.getValue().serial + ")"); + } + + Collections.sort(v); + StringBuilder sb = new StringBuilder(); + for (String s : v) { + sb.append(s); + } + node.serial = sb.toString(); + freq.put(node.serial, freq.getOrDefault(node.serial, 0) + 1); + } + + private void operate( + Trie node, + Map freq, + List path, + List> ans + ) { + if (freq.getOrDefault(node.serial, 0) > 1) return; + + if (!path.isEmpty()) { + ans.add(new ArrayList<>(path)); + } + + for (Map.Entry entry : node.children.entrySet()) { + path.add(entry.getKey()); + operate(entry.getValue(), freq, path, ans); + path.remove(path.size() - 1); + } + } +} \ No newline at end of file diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.js b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.js new file mode 100644 index 0000000000000..335607d205b81 --- /dev/null +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.js @@ -0,0 +1,50 @@ +var deleteDuplicateFolder = function (paths) { + class Trie { + constructor() { + this.serial = ""; + this.children = new Map(); + } + } + + const root = new Trie(); + for (const path of paths) { + let cur = root; + for (const node of path) { + if (!cur.children.has(node)) { + cur.children.set(node, new Trie()); + } + cur = cur.children.get(node); + } + } + + const freq = new Map(); + function construct(node) { + if (node.children.size === 0) return; + const v = []; + for (const [folder, child] of node.children) { + construct(child); + v.push(`${folder}(${child.serial})`); + } + v.sort(); + node.serial = v.join(""); + freq.set(node.serial, (freq.get(node.serial) || 0) + 1); + } + construct(root); + + const ans = []; + const path = []; + function operate(node) { + if ((freq.get(node.serial) || 0) > 1) return; + if (path.length > 0) { + ans.push([...path]); + } + for (const [folder, child] of node.children) { + path.push(folder); + operate(child); + path.pop(); + } + } + operate(root); + + return ans; +}; \ No newline at end of file diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.py b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.py new file mode 100644 index 0000000000000..f898e500b6a89 --- /dev/null +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.py @@ -0,0 +1,42 @@ +class Trie: + serial: str = "" + children: dict + + def __init__(self): + self.children = dict() + + +class Solution: + def deleteDuplicateFolder(self, paths: List[List[str]]) -> List[List[str]]: + root = Trie() + for path in paths: + cur = root + for node in path: + if node not in cur.children: + cur.children[node] = Trie() + cur = cur.children[node] + freq = Counter() + def construct(node: Trie) -> None: + if not node.children: + return + v = list() + for folder, child in node.children.items(): + construct(child) + v.append(folder + "(" + child.serial + ")") + v.sort() + node.serial = "".join(v) + freq[node.serial] += 1 + construct(root) + ans = list() + path = list() + def operate(node: Trie) -> None: + if freq[node.serial] > 1: + return + if path: + ans.append(path[:]) + for folder, child in node.children.items(): + path.append(folder) + operate(child) + path.pop() + operate(root) + return ans \ No newline at end of file From 78a3359ecd558ad99d9b36216a7075facef5eeec Mon Sep 17 00:00:00 2001 From: samarthswami1016 <70163465+samarthswami1016@users.noreply.github.com> Date: Sun, 20 Jul 2025 12:34:12 +0000 Subject: [PATCH 12/13] style: format code and docs with prettier --- .../1948.Delete Duplicate Folders in System/README.md | 2 +- .../1948.Delete Duplicate Folders in System/README_EN.md | 2 +- .../1948.Delete Duplicate Folders in System/solution.js | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md b/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md index a42a97fe21ade..0bc3ad3e1292a 100644 --- a/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md @@ -197,7 +197,7 @@ class Solution { } } - Map freq = new HashMap<>(); + Map freq = new HashMap<>(); construct(root, freq); List> ans = new ArrayList<>(); List path = new ArrayList<>(); diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md b/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md index 24574d0aef1f7..d5abd8efdcf54 100644 --- a/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md @@ -176,7 +176,7 @@ class Solution { } } - Map freq = new HashMap<>(); + Map freq = new HashMap<>(); construct(root, freq); List> ans = new ArrayList<>(); List path = new ArrayList<>(); diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.js b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.js index 335607d205b81..1beda7a1176a3 100644 --- a/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.js +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/solution.js @@ -1,7 +1,7 @@ var deleteDuplicateFolder = function (paths) { class Trie { constructor() { - this.serial = ""; + this.serial = ''; this.children = new Map(); } } @@ -26,7 +26,7 @@ var deleteDuplicateFolder = function (paths) { v.push(`${folder}(${child.serial})`); } v.sort(); - node.serial = v.join(""); + node.serial = v.join(''); freq.set(node.serial, (freq.get(node.serial) || 0) + 1); } construct(root); @@ -47,4 +47,4 @@ var deleteDuplicateFolder = function (paths) { operate(root); return ans; -}; \ No newline at end of file +}; From 9862d73c7204d795273460ad434cd890a89147f5 Mon Sep 17 00:00:00 2001 From: Samarth Swami Date: Sun, 20 Jul 2025 18:22:58 +0530 Subject: [PATCH 13/13] feat: add solutions to lc problem: No.1948 --- .../README.md | 182 +++++++++++++----- .../README_EN.md | 156 +++++++++++---- 2 files changed, 247 insertions(+), 91 deletions(-) diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md b/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md index 0bc3ad3e1292a..edd3073756909 100644 --- a/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/README.md @@ -5,11 +5,11 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/1900-1999/1948.De rating: 2533 source: 第 251 场周赛 Q4 tags: - - 字典树 - - 数组 - - 哈希表 - - 字符串 - - 哈希函数 + - 字典树 + - 数组 + - 哈希表 + - 字符串 + - 哈希函数 --- @@ -22,13 +22,27 @@ tags: -

由于一个漏洞,文件系统中存在许多重复文件夹。给你一个二维数组 paths,其中 paths[i] 是一个表示文件系统中第 i 个文件夹的绝对路径的数组。

+

+ 由于一个漏洞,文件系统中存在许多重复文件夹。给你一个二维数组{" "} + paths,其中 paths[i] 是一个表示文件系统中第{" "} + i 个文件夹的绝对路径的数组。 +

    -
  • 例如,["one", "two", "three"] 表示路径 "/one/two/three"
  • +
  • + 例如,["one", "two", "three"] 表示路径{" "} + "/one/two/three" 。 +
-

如果两个文件夹(不需要在同一层级)包含 非空且相同的 子文件夹 集合 并具有相同的子文件夹结构,则认为这两个文件夹是相同文件夹。相同文件夹的根层级 需要相同。如果存在两个(或两个以上)相同 文件夹,则需要将这些文件夹和所有它们的子文件夹 标记 为待删除。

+

+ 如果两个文件夹(不需要在同一层级)包含 非空且 + 相同的 子文件夹 集合{" "} + 并具有相同的子文件夹结构,则认为这两个文件夹是相同文件夹。相同文件夹的根层级{" "} + 需要相同。如果存在两个(或两个以上)相同{" "} + 文件夹,则需要将这些文件夹和所有它们的子文件夹 标记{" "} + 为待删除。 +

  • 例如,下面文件结构中的文件夹 "/a""/b" 相同。它们(以及它们的子文件夹)应该被 全部 标记为待删除: @@ -48,72 +62,136 @@ tags:
-

一旦所有的相同文件夹和它们的子文件夹都被标记为待删除,文件系统将会 删除 所有上述文件夹。文件系统只会执行一次删除操作。执行完这一次删除操作后,不会删除新出现的相同文件夹。

+

+ 一旦所有的相同文件夹和它们的子文件夹都被标记为待删除,文件系统将会{" "} + 删除{" "} + 所有上述文件夹。文件系统只会执行一次删除操作。执行完这一次删除操作后,不会删除新出现的相同文件夹。 +

-

返回二维数组 ans ,该数组包含删除所有标记文件夹之后剩余文件夹的路径。路径可以按 任意顺序 返回。

+

+ 返回二维数组 + ans{" "} + ,该数组包含删除所有标记文件夹之后剩余文件夹的路径。路径可以按{" "} + 任意顺序 返回。 +

 

-

示例 1:

- +

+ 示例 1: +

+
-输入:paths = [["a"],["c"],["d"],["a","b"],["c","b"],["d","a"]]
-输出:[["d"],["d","a"]]
-解释:文件结构如上所示。
-文件夹 "/a" 和 "/c"(以及它们的子文件夹)都会被标记为待删除,因为它们都包含名为 "b" 的空文件夹。
+  输入:paths =
+  [["a"],["c"],["d"],["a","b"],["c","b"],["d","a"]]
+  输出:[["d"],["d","a"]]
+  解释:文件结构如上所示。 文件夹 "/a" 和
+  "/c"(以及它们的子文件夹)都会被标记为待删除,因为它们都包含名为 "b"
+  的空文件夹。
 
-

示例 2:

- +

+ 示例 2: +

+
-输入:paths = [["a"],["c"],["a","b"],["c","b"],["a","b","x"],["a","b","x","y"],["w"],["w","y"]]
-输出:[["c"],["c","b"],["a"],["a","b"]]
-解释:文件结构如上所示。
-文件夹 "/a/b/x" 和 "/w"(以及它们的子文件夹)都会被标记为待删除,因为它们都包含名为 "y" 的空文件夹。
-注意,文件夹 "/a" 和 "/c" 在删除后变为相同文件夹,但这两个文件夹不会被删除,因为删除只会进行一次,且它们没有在删除前被标记。
+  输入:paths =
+  [["a"],["c"],["a","b"],["c","b"],["a","b","x"],["a","b","x","y"],["w"],["w","y"]]
+  输出:[["c"],["c","b"],["a"],["a","b"]]
+  解释:文件结构如上所示。 文件夹 "/a/b/x" 和
+  "/w"(以及它们的子文件夹)都会被标记为待删除,因为它们都包含名为 "y"
+  的空文件夹。 注意,文件夹 "/a" 和 "/c"
+  在删除后变为相同文件夹,但这两个文件夹不会被删除,因为删除只会进行一次,且它们没有在删除前被标记。
 
-

示例 3:

- +

+ 示例 3: +

+
-输入:paths = [["a","b"],["c","d"],["c"],["a"]]
-输出:[["c"],["c","d"],["a"],["a","b"]]
-解释:文件系统中所有文件夹互不相同。
-注意,返回的数组可以按不同顺序返回文件夹路径,因为题目对顺序没有要求。
+  输入:paths = [["a","b"],["c","d"],["c"],["a"]]
+  输出:[["c"],["c","d"],["a"],["a","b"]]
+  解释:文件系统中所有文件夹互不相同。
+  注意,返回的数组可以按不同顺序返回文件夹路径,因为题目对顺序没有要求。
 
-

示例 4:

- +

+ 示例 4: +

+
-输入:paths = [["a"],["a","x"],["a","x","y"],["a","z"],["b"],["b","x"],["b","x","y"],["b","z"]]
-输出:[]
-解释:文件结构如上所示。
-文件夹 "/a/x" 和 "/b/x"(以及它们的子文件夹)都会被标记为待删除,因为它们都包含名为 "y" 的空文件夹。
-文件夹 "/a" 和 "/b"(以及它们的子文件夹)都会被标记为待删除,因为它们都包含一个名为 "z" 的空文件夹以及上面提到的文件夹 "x" 。
+  输入:paths =
+  [["a"],["a","x"],["a","x","y"],["a","z"],["b"],["b","x"],["b","x","y"],["b","z"]]
+  输出:[]
+  解释:文件结构如上所示。 文件夹 "/a/x" 和
+  "/b/x"(以及它们的子文件夹)都会被标记为待删除,因为它们都包含名为 "y"
+  的空文件夹。 文件夹 "/a" 和
+  "/b"(以及它们的子文件夹)都会被标记为待删除,因为它们都包含一个名为 "z"
+  的空文件夹以及上面提到的文件夹 "x" 。
 
-

示例 5:

- +

+ 示例 5: +

+
-输入:paths = [["a"],["a","x"],["a","x","y"],["a","z"],["b"],["b","x"],["b","x","y"],["b","z"],["b","w"]]
-输出:[["b"],["b","w"],["b","z"],["a"],["a","z"]]
-解释:本例与上例的结构基本相同,除了新增 "/b/w" 文件夹。
-文件夹 "/a/x" 和 "/b/x" 仍然会被标记,但 "/a" 和 "/b" 不再被标记,因为 "/b" 中有名为 "w" 的空文件夹而 "/a" 没有。
-注意,"/a/z" 和 "/b/z" 不会被标记,因为相同子文件夹的集合必须是非空集合,但这两个文件夹都是空的。
+  输入:paths =
+  [["a"],["a","x"],["a","x","y"],["a","z"],["b"],["b","x"],["b","x","y"],["b","z"],["b","w"]]
+  输出:[["b"],["b","w"],["b","z"],["a"],["a","z"]]
+  解释:本例与上例的结构基本相同,除了新增 "/b/w" 文件夹。
+  文件夹 "/a/x" 和 "/b/x" 仍然会被标记,但 "/a" 和 "/b" 不再被标记,因为 "/b"
+  中有名为 "w" 的空文件夹而 "/a" 没有。 注意,"/a/z" 和 "/b/z"
+  不会被标记,因为相同子文件夹的集合必须是非空集合,但这两个文件夹都是空的。
 

 

-

提示:

+

+ 提示: +

    -
  • 1 <= paths.length <= 2 * 104
  • -
  • 1 <= paths[i].length <= 500
  • -
  • 1 <= paths[i][j].length <= 10
  • -
  • 1 <= sum(paths[i][j].length) <= 2 * 105
  • -
  • path[i][j] 由小写英文字母组成
  • -
  • 不会存在两个路径都指向同一个文件夹的情况
  • -
  • 对于不在根层级的任意文件夹,其父文件夹也会包含在输入中
  • +
  • + + 1 <= paths.length <= 2 * 104 + +
  • +
  • + 1 <= paths[i].length <= 500 +
  • +
  • + 1 <= paths[i][j].length <= 10 +
  • +
  • + + 1 <= sum(paths[i][j].length) <= 2 * 105 + +
  • +
  • + path[i][j] 由小写英文字母组成 +
  • +
  • 不会存在两个路径都指向同一个文件夹的情况
  • +
  • 对于不在根层级的任意文件夹,其父文件夹也会包含在输入中
@@ -381,4 +459,4 @@ func deleteDuplicateFolder(paths [][]string) [][]string { - + \ No newline at end of file diff --git a/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md b/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md index d5abd8efdcf54..a46d62426501f 100644 --- a/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md +++ b/solution/1900-1999/1948.Delete Duplicate Folders in System/README_EN.md @@ -5,11 +5,11 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/1900-1999/1948.De rating: 2533 source: Weekly Contest 251 Q4 tags: - - Trie - - Array - - Hash Table - - String - - Hash Function + - Trie + - Array + - Hash Table + - String + - Hash Function --- @@ -22,13 +22,32 @@ tags: -

Due to a bug, there are many duplicate folders in a file system. You are given a 2D array paths, where paths[i] is an array representing an absolute path to the ith folder in the file system.

+

+ Due to a bug, there are many duplicate folders in a file system. You are given + a 2D array paths, where paths[i] is an array + representing an absolute path to the{" "} + + ith + {" "} + folder in the file system. +

    -
  • For example, ["one", "two", "three"] represents the path "/one/two/three".
  • +
  • + For example,{" "} + ["one", "two", "three"]{" "} + represents the path "/one/two/three". +
-

Two folders (not necessarily on the same level) are identical if they contain the same non-empty set of identical subfolders and underlying subfolder structure. The folders do not need to be at the root level to be identical. If two or more folders are identical, then mark the folders as well as all their subfolders.

+

+ Two folders (not necessarily on the same level) are identical{" "} + if they contain the same non-empty set of identical + subfolders and underlying subfolder structure. The folders{" "} + do not need to be at the root level to be identical. If two + or more folders are identical, then mark the + folders as well as all their subfolders. +

  • For example, folders "/a" and "/b" in the file structure below are identical. They (as well as their subfolders) should all be marked: @@ -48,51 +67,110 @@ tags:
-

Once all the identical folders and their subfolders have been marked, the file system will delete all of them. The file system only runs the deletion once, so any folders that become identical after the initial deletion are not deleted.

- -

Return the 2D array ans containing the paths of the remaining folders after deleting all the marked folders. The paths may be returned in any order.

+

+ Once all the identical folders and their subfolders have been marked, the file + system will delete all of them. The file system only runs the + deletion once, so any folders that become identical after the initial deletion + are not deleted. +

+ +

+ Return the 2D array + ans{" "} + + containing the paths of the remaining folders after + deleting all the marked folders. The paths may be returned in{" "} + any order + + . +

 

-

Example 1:

- +

+ Example 1: +

+
-Input: paths = [["a"],["c"],["d"],["a","b"],["c","b"],["d","a"]]
-Output: [["d"],["d","a"]]
-Explanation: The file structure is as shown.
-Folders "/a" and "/c" (and their subfolders) are marked for deletion because they both contain an empty
-folder named "b".
+  Input: paths =
+  [["a"],["c"],["d"],["a","b"],["c","b"],["d","a"]]
+  Output: [["d"],["d","a"]]
+  Explanation: The file structure is as shown. Folders
+  "/a" and "/c" (and their subfolders) are marked for
+  deletion because they both contain an empty folder named "b".
 
-

Example 2:

- +

+ Example 2: +

+
-Input: paths = [["a"],["c"],["a","b"],["c","b"],["a","b","x"],["a","b","x","y"],["w"],["w","y"]]
-Output: [["c"],["c","b"],["a"],["a","b"]]
-Explanation: The file structure is as shown. 
-Folders "/a/b/x" and "/w" (and their subfolders) are marked for deletion because they both contain an empty folder named "y".
-Note that folders "/a" and "/c" are identical after the deletion, but they are not deleted because they were not marked beforehand.
+  Input: paths =
+  [["a"],["c"],["a","b"],["c","b"],["a","b","x"],["a","b","x","y"],["w"],["w","y"]]
+  Output:{" "}
+  [["c"],["c","b"],["a"],["a","b"]]
+  Explanation: The file structure is as shown. Folders
+  "/a/b/x" and "/w" (and their subfolders) are marked for
+  deletion because they both contain an empty folder named "y". Note
+  that folders "/a" and "/c" are identical after the
+  deletion, but they are not deleted because they were not marked beforehand.
 
-

Example 3:

- +

+ Example 3: +

+
-Input: paths = [["a","b"],["c","d"],["c"],["a"]]
-Output: [["c"],["c","d"],["a"],["a","b"]]
-Explanation: All folders are unique in the file system.
-Note that the returned array can be in a different order as the order does not matter.
+  Input: paths =
+  [["a","b"],["c","d"],["c"],["a"]]
+  Output:{" "}
+  [["c"],["c","d"],["a"],["a","b"]]
+  Explanation: All folders are unique in the file system. Note
+  that the returned array can be in a different order as the order does not
+  matter.
 

 

-

Constraints:

+

+ Constraints: +

    -
  • 1 <= paths.length <= 2 * 104
  • -
  • 1 <= paths[i].length <= 500
  • -
  • 1 <= paths[i][j].length <= 10
  • -
  • 1 <= sum(paths[i][j].length) <= 2 * 105
  • -
  • path[i][j] consists of lowercase English letters.
  • -
  • No two paths lead to the same folder.
  • -
  • For any folder not at the root level, its parent folder will also be in the input.
  • +
  • + + 1 <= paths.length <= 2 * 104 + +
  • +
  • + 1 <= paths[i].length <= 500 +
  • +
  • + 1 <= paths[i][j].length <= 10 +
  • +
  • + + 1 <= sum(paths[i][j].length) <= 2 * 105 + +
  • +
  • + path[i][j] consists of lowercase English letters. +
  • +
  • No two paths lead to the same folder.
  • +
  • + For any folder not at the root level, its parent folder will also be in the + input. +