├── README.md ├── 2019-december ├── assignments │ ├── 1.advanced-dp.pdf │ ├── 2.graph problems.pdf │ ├── 4.range query problems.pdf │ └── 3.graph optimization problems.pdf ├── 2.graph problems │ ├── disjointset │ │ ├── IDisjointSet.java │ │ ├── Test.java │ │ ├── WeightedUnionDS.java │ │ └── WeightedUnionPathCompressionDS.java │ ├── AllSimplePaaths.java │ ├── CountIslands.java │ ├── GraphUtils.java │ ├── OddLengthCycle.java │ ├── CourseSchedule.java │ ├── CountFriendCircles.java │ ├── GraphCycle.java │ └── AllPairsShortestPath.java ├── 3.range query problems │ └── src │ │ └── com │ │ └── alg │ │ └── advtop20 │ │ ├── segmentree │ │ ├── ISegmentTree.java │ │ ├── TestSegmentTree.java │ │ ├── SeqSegmentTree.java │ │ └── LinkedSegmentTree.java │ │ ├── rangequery1d │ │ ├── RangeSum1.java │ │ ├── RangeSum3.java │ │ └── RangeSum2.java │ │ └── quadtree │ │ ├── TestPRQuadTree.java │ │ ├── TestMXQuadTree.java │ │ ├── MXQuadTree.java │ │ └── PRQuadTree.java └── 1.advanced dp │ ├── LongIncrSubseq2.java │ ├── dp3 │ ├── LongIncrSubseq2.java │ ├── MyInteger.java │ └── LongIncrSubseq1.java │ ├── MyInteger.java │ ├── dp1 │ ├── MyInteger.java │ ├── BSTCount.java │ ├── AllPairsPalCheck.java │ ├── MinCutPalPartitioning1.java │ ├── MinCutPalPartitioning2.java │ └── RestaurantMerging.java │ ├── BSTCount.java │ ├── LongIncrSubseq1.java │ ├── SubsetSum.java │ ├── dp2 │ └── SubsetSum.java │ ├── AllPairsPalCheck.java │ ├── MinCutPalPartitioning1.java │ ├── MinCutPalPartitioning2.java │ └── RestaurantMerging.java ├── 2017-may ├── 1.tree problems │ └── src │ │ └── com │ │ └── alg │ │ └── top20 │ │ └── adv │ │ ├── TreeNode.java │ │ ├── TreeTraversal.java │ │ ├── BSTCounting.java │ │ ├── BinaryTreeUtils.java │ │ └── MaxSumNoAdjacent.java ├── 4.string problems │ └── src │ │ └── com │ │ └── alg │ │ └── top20 │ │ └── adv │ │ └── strings │ │ ├── LongestPalSubsequence.java │ │ ├── EditDistance.java │ │ └── StringInterleave.java ├── 5.grid-problems │ └── src │ │ └── com │ │ └── alg │ │ └── top20 │ │ └── adv │ │ └── grid │ │ └── GridSearch.java ├── 3.backtracking │ └── src │ │ └── com │ │ └── alg │ │ └── top20 │ │ └── bt │ │ ├── Nqueens.java │ │ └── SudokuSolver.java └── 2.dynamic programming │ └── src │ └── com │ └── alg │ └── top20 │ └── adv │ └── dp │ └── LISLength.java └── 2018-aug ├── 1.range-query problems └── src │ └── com │ └── alg │ └── advtop20 │ ├── rangequery │ ├── oned │ │ ├── RangeSum1.java │ │ ├── RangeSum2.java │ │ ├── RangeSum3.java │ │ ├── RangeSum5.java │ │ └── RangeSum4.java │ └── twod │ │ ├── RangeSum1.java │ │ ├── RangeSum2.java │ │ ├── RangeSum4.java │ │ └── RangeSum3.java │ ├── graph-problems │ ├── traversal │ │ ├── AllSimplePaths.java │ │ ├── Bipartitionable.java │ │ ├── CycleDetection.java │ │ ├── GraphUtils.java │ │ ├── CourseSchedule.java │ │ └── CountFriendCircles.java │ ├── src │ │ └── com │ │ │ └── alg │ │ │ └── advtop20 │ │ │ └── graphs │ │ │ └── traversal │ │ │ ├── AllSimplePaths.java │ │ │ ├── Bipartitionable.java │ │ │ ├── CycleDetection.java │ │ │ ├── GraphUtils.java │ │ │ ├── CourseSchedule.java │ │ │ └── CountFriendCircles.java │ └── st │ │ └── MinimumRentalConnections.java │ └── grid-problems │ └── src │ └── com │ └── alg │ └── advtop20 │ └── grid │ ├── DisjointSet1.java │ ├── DisjointSet2.java │ ├── CountRegions2.java │ ├── CountRegions.java │ └── CountRegions1.java ├── 3.graph-problems └── src │ └── com │ └── alg │ └── advtop20 │ └── graphs │ ├── traversal │ ├── allpaths │ │ └── AllSimplePaths.java │ ├── bipartionable │ │ └── Bipartitionable.java │ ├── cycledetect │ │ └── CycleDetection.java │ ├── courseschedule │ │ └── CourseSchedule.java │ ├── friendcircles │ │ └── CountFriendCircles.java │ └── countregions │ │ └── CountRegions.java │ ├── st │ └── MinimumRentalConnections.java │ ├── GraphUtils.java │ └── shortestpaths │ └── ShortestPaths.java ├── 2.advanced-dp problems └── src │ └── com │ └── alg │ └── advtop20 │ └── dp │ ├── StringInterleaving.java │ └── MinCutPalPartition.java └── 4.file-problems └── src └── com └── alg └── advtop20 └── files └── Tail.java /README.md: -------------------------------------------------------------------------------- 1 | # advanced-top20 2 | It consists of all code examples of advanced top-20(problem solving) course taken at algorithmica across all years 3 | -------------------------------------------------------------------------------- /2019-december/assignments/1.advanced-dp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algorithmica-repository/advanced-top20/HEAD/2019-december/assignments/1.advanced-dp.pdf -------------------------------------------------------------------------------- /2019-december/assignments/2.graph problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algorithmica-repository/advanced-top20/HEAD/2019-december/assignments/2.graph problems.pdf -------------------------------------------------------------------------------- /2019-december/assignments/4.range query problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algorithmica-repository/advanced-top20/HEAD/2019-december/assignments/4.range query problems.pdf -------------------------------------------------------------------------------- /2019-december/assignments/3.graph optimization problems.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algorithmica-repository/advanced-top20/HEAD/2019-december/assignments/3.graph optimization problems.pdf -------------------------------------------------------------------------------- /2019-december/2.graph problems/disjointset/IDisjointSet.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph.disjointset; 2 | 3 | public interface IDisjointSet { 4 | int find(int x); 5 | void union(int x, int y); 6 | void display(); 7 | int size(); 8 | } 9 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/segmentree/ISegmentTree.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.segmentree; 2 | 3 | public interface ISegmentTree { 4 | void update(int i, int x); 5 | int rangeSum(int i, int j); 6 | void display(); 7 | } 8 | -------------------------------------------------------------------------------- /2017-may/1.tree problems/src/com/alg/top20/adv/TreeNode.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.adv; 2 | 3 | 4 | public class TreeNode { 5 | Integer data; 6 | TreeNode left; 7 | TreeNode right; 8 | 9 | TreeNode(Integer data) { 10 | this.data = data; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/LongIncrSubseq2.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp3; 2 | 3 | public class LongIncrSubseq2 { 4 | 5 | public static int lis32(int[] in) { 6 | return 0; 7 | } 8 | 9 | public static void main(String[] args) { 10 | // TODO Auto-generated method stub 11 | 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/dp3/LongIncrSubseq2.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp3; 2 | 3 | public class LongIncrSubseq2 { 4 | 5 | public static int lis32(int[] in) { 6 | return 0; 7 | } 8 | 9 | public static void main(String[] args) { 10 | // TODO Auto-generated method stub 11 | 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/MyInteger.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp3; 2 | 3 | public class MyInteger { 4 | private int value; 5 | 6 | public MyInteger(int value) { 7 | this.value = value; 8 | } 9 | 10 | public int get() { 11 | return value; 12 | } 13 | 14 | public void set(int value) { 15 | this.value = value; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/dp1/MyInteger.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp1; 2 | 3 | public class MyInteger { 4 | private int value; 5 | 6 | public MyInteger(int value) { 7 | this.value = value; 8 | } 9 | 10 | public int get() { 11 | return value; 12 | } 13 | 14 | public void set(int value) { 15 | this.value = value; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/dp3/MyInteger.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp3; 2 | 3 | public class MyInteger { 4 | private int value; 5 | 6 | public MyInteger(int value) { 7 | this.value = value; 8 | } 9 | 10 | public int get() { 11 | return value; 12 | } 13 | 14 | public void set(int value) { 15 | this.value = value; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/rangequery/oned/RangeSum1.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery.oned; 2 | 3 | public class RangeSum1 { 4 | private int[] in; 5 | 6 | public RangeSum1(int[] in) { 7 | this.in = in; 8 | } 9 | //O(1) 10 | public void update(int i, int x) { 11 | in[i] = x; 12 | } 13 | //O(n) 14 | public int rangeSum(int i, int j) { 15 | int sum = 0; 16 | for(int k = i; k <= j; ++k) 17 | sum += in[k]; 18 | return sum; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/rangequery/twod/RangeSum1.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery.twod; 2 | 3 | public class RangeSum1 { 4 | private int[] in; 5 | 6 | public RangeSum1(int[] in) { 7 | this.in = in; 8 | } 9 | //O(1) 10 | public void update(int i, int x) { 11 | in[i] = x; 12 | } 13 | //O(n) 14 | public int rangeSum(int i, int j) { 15 | int sum = 0; 16 | for(int k = i; k <= j; ++k) 17 | sum += in[k]; 18 | return sum; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/rangequery1d/RangeSum1.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery1d; 2 | 3 | public class RangeSum1 { 4 | private int[] in; 5 | 6 | public RangeSum1(int[] in) { 7 | this.in = in; 8 | } 9 | 10 | public void update(int i, int x) { 11 | in[i] = x; 12 | } 13 | public int rangeSum(int i, int j) { 14 | int sum = 0; 15 | for(int k = i; k <= j; ++k) 16 | sum += in[k]; 17 | return sum; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/rangequery1d/RangeSum3.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery1d; 2 | 3 | import com.alg.advtop20.rangesum.segtree.ISegmentTree; 4 | import com.alg.advtop20.rangesum.segtree.SeqSegmentTree; 5 | 6 | public class RangeSum3 { 7 | private ISegmentTree tree; 8 | 9 | public RangeSum3(int[] in) { 10 | tree = new SeqSegmentTree(in); 11 | } 12 | 13 | public void update(int i, int x) { 14 | tree.update(i, x); 15 | } 16 | 17 | public int rangeSum(int i, int j) { 18 | return tree.rangeSum(i, j); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/rangequery1d/RangeSum2.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery1d; 2 | 3 | public class RangeSum2 { 4 | private int[] in; 5 | private int[] csum; 6 | 7 | public RangeSum2(int[] in) { 8 | this.in = in; 9 | for (int k = 0; k < in.length; ++k) { 10 | csum[k] = (k != 0 ? csum[k - 1] : 0) + in[k]; 11 | } 12 | } 13 | 14 | public void update(int i, int x) { 15 | in[i] = x; 16 | for (int k = i; k < in.length; ++k) { 17 | csum[k] = (k != 0 ? csum[k - 1] : 0) + in[k]; 18 | } 19 | } 20 | 21 | public int rangeSum(int i, int j) { 22 | return csum[j] - (i != 0 ? csum[i - 1] : 0); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/rangequery/oned/RangeSum2.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery.oned; 2 | 3 | public class RangeSum2 { 4 | private int[] in; 5 | private int[] csum; 6 | 7 | //O(n) 8 | public RangeSum2(int[] in) { 9 | this.in = in; 10 | csum = new int[in.length]; 11 | csum[0] = in[0]; 12 | for(int i = 1; i < csum.length; ++i) 13 | csum[i] = csum[i-1] + in[i]; 14 | } 15 | //O(n) 16 | public void update(int i, int x) { 17 | in[i] = x; 18 | for(int k = i; k <= csum.length; ++k) 19 | csum[k] = csum[k-1] + in[k]; 20 | } 21 | //O(1) 22 | public int rangeSum(int i, int j) { 23 | if(i == 0) return csum[j]; 24 | return csum[j] - csum[i-1]; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/rangequery/twod/RangeSum2.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery.twod; 2 | 3 | public class RangeSum2 { 4 | private int[] in; 5 | private int[] csum; 6 | 7 | //O(n) 8 | public RangeSum2(int[] in) { 9 | this.in = in; 10 | csum = new int[in.length]; 11 | csum[0] = in[0]; 12 | for(int i = 1; i < csum.length; ++i) 13 | csum[i] = csum[i-1] + in[i]; 14 | } 15 | //O(n) 16 | public void update(int i, int x) { 17 | in[i] = x; 18 | for(int k = i; k <= csum.length; ++k) 19 | csum[k] = csum[k-1] + in[k]; 20 | } 21 | //O(1) 22 | public int rangeSum(int i, int j) { 23 | if(i == 0) return csum[j]; 24 | return csum[j] - csum[i-1]; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/segmentree/TestSegmentTree.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.segmentree; 2 | 3 | import java.util.Random; 4 | 5 | public class TestSegmentTree { 6 | 7 | public static void main(String[] args) { 8 | int n = Integer.parseInt(args[0]); 9 | int[] in = new int[n]; 10 | Random r = new Random(100); 11 | for (int i = 0; i < n; ++i) 12 | in[i] = r.nextInt(5); 13 | ISegmentTree rs = new LinkedSegmentTree(in); 14 | rs.display(); 15 | rs.update(0, -2); 16 | rs.display(); 17 | for (int i = 0; i < n; ++i) { 18 | for (int j = i + 1; j < n; ++j) { 19 | System.out.println(rs.rangeSum(i, j)); 20 | } 21 | } 22 | 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/disjointset/Test.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph.disjointset; 2 | 3 | import java.util.Random; 4 | 5 | public class Test { 6 | 7 | public static void test1(IDisjointSet dset) { 8 | Random r = new Random(0); 9 | int n = dset.size(); 10 | dset.display(); 11 | for (int i = 0; i < n; ++i) { 12 | int first = r.nextInt(n); 13 | int second = r.nextInt(n); 14 | dset.union(first, second); 15 | System.out.println("union of sets:" + first + "," + second); 16 | dset.display(); 17 | } 18 | System.out.println(dset.size()); 19 | System.out.println(dset.find(0)); 20 | System.out.println(dset.find(n-1)); 21 | } 22 | 23 | public static void main(String[] args) { 24 | int n = Integer.parseInt(args[0]); 25 | test1(new WeightedUnionDS(n)); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/quadtree/TestPRQuadTree.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.quadtree; 2 | 3 | import java.util.Random; 4 | 5 | public class TestPRQuadTree { 6 | 7 | public static void main(String[] args) { 8 | int n = Integer.parseInt(args[0]); 9 | PRQuadTree tree = new PRQuadTree(new Rectangle(0, 0, 100, 100), 5); 10 | 11 | Random r = new Random(100); 12 | for (int i = 0; i < n; ++i) { 13 | int x = r.nextInt(100) + 1; 14 | int y = r.nextInt(100) + 1; 15 | Point point = new Point(x, y); 16 | tree.add(point); 17 | System.out.println(point); 18 | tree.display(); 19 | } 20 | System.out.println(tree.rangeQuery(new Rectangle(0, 0, 50, 50))); 21 | System.out.println(tree.rangeQuery(new Rectangle(30, 30, 50, 50))); 22 | System.out.println(tree.rangeQuery(new Rectangle(50, 50, 70, 70))); 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/AllSimplePaaths.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph; 2 | 3 | public class AllSimplePaaths { 4 | 5 | public static void allSimplePaths(int s, int t, int[][] in) { 6 | boolean[] visit = new boolean[in.length]; 7 | auxPaths(s, t, in, visit, s+""); 8 | } 9 | private static void auxPaths(int u, int t, int[][] in, boolean[] visit, String path) { 10 | if(u == t) { 11 | System.out.println(path); 12 | return; 13 | } 14 | visit[u] = true; 15 | for(int v = 0; v < in.length; ++v) { 16 | if(in[u][v] == 1) { 17 | if(visit[v] == false) 18 | auxPaths(v, t, in, visit, path+"->"+v); 19 | } 20 | } 21 | visit[u] = false; 22 | } 23 | public static void main(String[] args) { 24 | int n = Integer.parseInt(args[0]); 25 | int[][] in = GraphUtils.undirectedCompleteGraph(n); 26 | GraphUtils.display(in); 27 | allSimplePaths(0, n-1, in); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /2017-may/4.string problems/src/com/alg/top20/adv/strings/LongestPalSubsequence.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.adv.strings; 2 | 3 | import java.util.Arrays; 4 | 5 | public class LongestPalSubsequence { 6 | 7 | private static void display(int[][] mem) { 8 | for(int i = 0; i < mem.length; ++i) 9 | System.out.println(Arrays.toString(mem[i])); 10 | } 11 | public static int longestPalSubSeq3(String s) { 12 | int n = s.length(); 13 | int[][] mem = new int[n+1][n+1]; 14 | for(int i = 1; i <= n; ++i) 15 | mem[i][i] = 1; 16 | for(int l = 1; l < n; ++l) { 17 | for(int i = 1; i <= n-l; ++i) { 18 | int j = i + l; 19 | if(s.charAt(i-1) == s.charAt(j-1)) 20 | mem[i][j] = 2 + mem[i+1][j-1]; 21 | else 22 | mem[i][j] = Math.max(mem[i+1][j], mem[i][j-1]); 23 | } 24 | } 25 | display(mem); 26 | return mem[1][n]; 27 | } 28 | public static void main(String[] args) { 29 | System.out.println(longestPalSubSeq3(args[0])); 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/traversal/AllSimplePaths.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | public class AllSimplePaths { 4 | 5 | private static void auxPaths(int s, int t, int[][] in, boolean[] visit, String prefix) { 6 | if(s == t) { 7 | System.out.println(prefix +"->" + t); 8 | return; 9 | } 10 | visit[s] = true; 11 | for(int v = 0; v < in.length; ++v) { 12 | if(in[s][v] == 1 && visit[v] == false) 13 | auxPaths(v, t, in, visit, prefix+"->"+s); 14 | } 15 | visit[s] = false; 16 | } 17 | //TC:O(V!) ~ O(V ^ V) SC:O(V) 18 | public static void allSimplePaths(int s, int t, int[][] in) { 19 | boolean[] visit = new boolean[in.length]; 20 | auxPaths(s, t, in, visit, ""); 21 | } 22 | public static void main(String[] args) { 23 | int n = Integer.parseInt(args[0]); 24 | int[][] in = GraphUtils.completeGraph(n); 25 | GraphUtils.printGraph(in); 26 | allSimplePaths(0, n-1, in); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/src/com/alg/advtop20/graphs/traversal/AllSimplePaths.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | public class AllSimplePaths { 4 | 5 | private static void auxPaths(int s, int t, int[][] in, boolean[] visit, String prefix) { 6 | if(s == t) { 7 | System.out.println(prefix +"->" + t); 8 | return; 9 | } 10 | visit[s] = true; 11 | for(int v = 0; v < in.length; ++v) { 12 | if(in[s][v] == 1 && visit[v] == false) 13 | auxPaths(v, t, in, visit, prefix+"->"+s); 14 | } 15 | visit[s] = false; 16 | } 17 | //TC:O(V!) ~ O(V ^ V) SC:O(V) 18 | public static void allSimplePaths(int s, int t, int[][] in) { 19 | boolean[] visit = new boolean[in.length]; 20 | auxPaths(s, t, in, visit, ""); 21 | } 22 | public static void main(String[] args) { 23 | int n = Integer.parseInt(args[0]); 24 | int[][] in = GraphUtils.completeGraph(n); 25 | GraphUtils.printGraph(in); 26 | allSimplePaths(0, n-1, in); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /2018-aug/3.graph-problems/src/com/alg/advtop20/graphs/traversal/allpaths/AllSimplePaths.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal.allpaths; 2 | 3 | import com.alg.advtop20.graphs.GraphUtils; 4 | 5 | public class AllSimplePaths { 6 | 7 | private static void auxPaths(int s, int t, int[][] in, boolean[] visit, String prefix) { 8 | if(s == t) { 9 | System.out.println(prefix +"->" + t); 10 | return; 11 | } 12 | visit[s] = true; 13 | for(int v = 0; v < in.length; ++v) { 14 | if(in[s][v] == 1 && visit[v] == false) 15 | auxPaths(v, t, in, visit, prefix+"->"+s); 16 | } 17 | visit[s] = false; 18 | } 19 | //TC:O(V!) ~ O(V ^ V) SC:O(V) 20 | public static void allSimplePaths(int s, int t, int[][] in) { 21 | boolean[] visit = new boolean[in.length]; 22 | auxPaths(s, t, in, visit, ""); 23 | } 24 | public static void main(String[] args) { 25 | int n = Integer.parseInt(args[0]); 26 | int[][] in = GraphUtils.completeGraph(n); 27 | GraphUtils.printGraph(in); 28 | allSimplePaths(0, n-1, in); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/grid-problems/src/com/alg/advtop20/grid/DisjointSet1.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.grid; 2 | 3 | import java.util.Arrays; 4 | 5 | public class DisjointSet1 { 6 | private int[] parent; 7 | int nsets; 8 | 9 | public DisjointSet1(int[][] in) { 10 | int n = in.length * in.length; 11 | parent = new int[n]; 12 | for(int i = 0; i < n; ++i) { 13 | parent[i] = i; 14 | } 15 | for(int i = 0; i < in.length; ++i) { 16 | for(int j = 0; j < in.length; ++j) { 17 | if(in[i][j] == 1) 18 | ++nsets; 19 | } 20 | } 21 | } 22 | 23 | public int find(int x) { 24 | while(parent[x] != x) 25 | x = parent[x]; 26 | return x; 27 | } 28 | 29 | public void union(int x, int y) { 30 | int rx = find(x); 31 | int ry = find(y); 32 | if(rx != ry) { 33 | parent[rx] = ry; 34 | --nsets; 35 | } 36 | } 37 | 38 | public int getNumSets() { 39 | return nsets; 40 | } 41 | 42 | public void display() { 43 | System.out.println(Arrays.toString(parent)); 44 | System.out.println(nsets); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/quadtree/TestMXQuadTree.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.quadtree; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | public class TestMXQuadTree { 7 | 8 | public static void displayGrid(int[][] in) { 9 | for (int[] tmp : in) 10 | System.out.println(Arrays.toString(tmp)); 11 | } 12 | 13 | public static void main(String[] args) { 14 | int n = Integer.parseInt(args[0]); 15 | int[][] in = new int[n][n]; 16 | Random r = new Random(100); 17 | for (int i = 0; i < n; ++i) 18 | for (int j = 0; j < n; ++j) 19 | in[i][j] = r.nextInt(n); 20 | MXQuadTree tree = new MXQuadTree(in); 21 | displayGrid(in); 22 | tree.display(); 23 | tree.update(1, 1, -1); 24 | displayGrid(in); 25 | tree.display(); 26 | System.out.println(tree.rangeQuery(new Rectangle(1, 1, n - 2, n - 2))); 27 | System.out.println(tree.rangeQuery(new Rectangle(0, 0, n - 1, 0))); 28 | System.out.println(tree.rangeQuery(new Rectangle(0, n - 1, n - 1, n - 1))); 29 | System.out.println(tree.rangeQuery(new Rectangle(0, 0, 0, n - 1))); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/CountIslands.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph; 2 | 3 | public class CountIslands { 4 | 5 | public static int countIslands1(int[][] in) { 6 | int n = in.length; 7 | int m = in[0].length; 8 | boolean[][] visit = new boolean[n][m]; 9 | int count = 0; 10 | for (int i = 0; i < n; ++i) { 11 | for (int j = 0; j < m; ++j) { 12 | if (in[i][j] == 1 && visit[i][j] == false) { 13 | dfs(i, j, in, visit); 14 | ++count; 15 | } 16 | } 17 | } 18 | return count; 19 | } 20 | 21 | private static void dfs(int i, int j, int[][] in, boolean[][] visit) { 22 | visit[i][j] = true; 23 | int n = in.length; 24 | int m = in[0].length; 25 | int[][] neighbours = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } }; 26 | for (int k = 0; k < neighbours.length; ++k) { 27 | int r = neighbours[k][0]; 28 | int c = neighbours[k][1]; 29 | if (i + r >= 0 && i + r < n && j + c >= 0 && j + c < m && in[i + r][j + c] == 1 30 | && visit[i + r][j + c] == false) 31 | dfs(i + r, j + c, in, visit); 32 | } 33 | } 34 | 35 | public static void main(String[] args) { 36 | // TODO Auto-generated method stub 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /2017-may/5.grid-problems/src/com/alg/top20/adv/grid/GridSearch.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.adv.grid; 2 | 3 | import java.util.HashMap; 4 | 5 | 6 | public class GridSearch { 7 | 8 | //TC:O(n ^ 3) SC:O(n ^ 2) ~ n ^ 2 + n 9 | public static boolean hasWord(char[][] grid, String word) { 10 | boolean[][] visit = new boolean[grid.length][grid.length]; 11 | for(int i = 0; i < grid.length; ++i) { 12 | for(int j = 0; j < grid.length; ++j) { 13 | if(auxHasWord(i, j, grid, word, visit) == true) 14 | return true; 15 | } 16 | } 17 | return false; 18 | } 19 | private static boolean auxHasWord(int i, int j, char[][] grid, String word, boolean[][] visit) { 20 | if(word.length() == 0) return true; 21 | if(visit[i][j]== true) return false; 22 | if(grid[i][j] != word.charAt(0)) return false; 23 | visit[i][j] = true; 24 | word = word.substring(1); 25 | boolean res = auxHasWord(i+1, j, grid, word, visit) || 26 | auxHasWord(i-1, j, grid, word, visit) || 27 | auxHasWord(i, j-1, grid, word, visit) || 28 | auxHasWord(i, j+1, grid, word, visit); 29 | visit[i][j] = false; 30 | return res; 31 | } 32 | 33 | public static void main(String[] args) { 34 | // TODO Auto-generated method stub 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/disjointset/WeightedUnionDS.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph.disjointset; 2 | 3 | import java.util.Arrays; 4 | 5 | public class WeightedUnionDS implements IDisjointSet { 6 | private int size; 7 | private int[] parent; 8 | private int[] weights; 9 | 10 | public WeightedUnionDS(int n) { 11 | parent = new int[n]; 12 | weights = new int[n]; 13 | for(int i = 0; i < n; ++i) { 14 | parent[i] = i; 15 | weights[i] = 1; 16 | } 17 | size = n; 18 | } 19 | 20 | @Override 21 | public int find(int x) { 22 | while(parent[x] != x) 23 | x = parent[x]; 24 | return x; 25 | } 26 | 27 | @Override 28 | public void union(int x, int y) { 29 | int idx = find(x); 30 | int idy = find(y); 31 | if(idx == idy) return ; 32 | --size; 33 | if(weights[idx] > weights[idy]) { 34 | parent[idy] = idx; 35 | weights[idx] += weights[idy]; 36 | } else { 37 | parent[idx] = idy; 38 | weights[idy] += weights[idx]; 39 | } 40 | } 41 | 42 | @Override 43 | public void display() { 44 | System.out.println(Arrays.toString(parent)); 45 | System.out.println(Arrays.toString(weights)); 46 | } 47 | 48 | @Override 49 | public int size() { 50 | return size; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/GraphUtils.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | public class GraphUtils { 7 | 8 | public static int[][] undirectedRandomGraph(int n) { 9 | int[][] in = new int[n][n]; 10 | Random r = new Random(0); 11 | int nedges = n; 12 | for (int i = 0; i < nedges; ++i) { 13 | int u = r.nextInt(n); 14 | int v = r.nextInt(n); 15 | if(u != v) 16 | in[u][v] = in[v][u] = 1; 17 | } 18 | return in; 19 | } 20 | 21 | public static int[][] undirectedCompleteGraph(int n) { 22 | int[][] in = new int[n][n]; 23 | for (int u = 0; u < n; ++u) { 24 | for (int v = u + 1; v < n; ++v) 25 | in[u][v] = in[v][u] = 1; 26 | } 27 | return in; 28 | } 29 | 30 | public static int[][] directedCompleteGraph(int n) { 31 | int[][] in = new int[n][n]; 32 | for (int u = 0; u < n; ++u) { 33 | for (int v = u + 1; v < n; ++v) 34 | in[u][v] = 1; 35 | } 36 | return in; 37 | } 38 | 39 | 40 | public static void display(int[][] in) { 41 | for (int[] tmp : in) { 42 | System.out.println(Arrays.toString(tmp)); 43 | } 44 | } 45 | 46 | public static void main(String[] args) { 47 | // TODO Auto-generated method stub 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/grid-problems/src/com/alg/advtop20/grid/DisjointSet2.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.grid; 2 | 3 | import java.util.Arrays; 4 | 5 | public class DisjointSet2 { 6 | private int[] parent; 7 | private int[] rank; 8 | int nsets; 9 | 10 | public DisjointSet2(int[][] in) { 11 | int n = in.length * in.length; 12 | parent = new int[n]; 13 | rank = new int[n]; 14 | for(int i = 0; i < n; ++i) { 15 | parent[i] = i; 16 | rank[i] = 1; 17 | } 18 | for(int i = 0; i < in.length; ++i) { 19 | for(int j = 0; j < in.length; ++j) { 20 | if(in[i][j] == 1) 21 | ++nsets; 22 | } 23 | } 24 | } 25 | 26 | public int find(int x) { 27 | if(parent[x] == x) return x; 28 | return parent[x] = find(parent[x]); 29 | } 30 | 31 | public void union(int x, int y) { 32 | int rx = find(x); 33 | int ry = find(y); 34 | if(rx != ry) { 35 | --nsets; 36 | if(rank[rx] > rank[ry]) 37 | parent[ry] = rx; 38 | else if(rank[ry] > rank[rx]) 39 | parent[rx] = ry; 40 | else { 41 | parent[ry] = rx; 42 | ++rank[rx]; 43 | } 44 | } 45 | } 46 | 47 | public int getNumSets() { 48 | return nsets; 49 | } 50 | 51 | public void display() { 52 | System.out.println(Arrays.toString(parent)); 53 | System.out.println(Arrays.toString(rank)); 54 | } 55 | 56 | } 57 | 58 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/grid-problems/src/com/alg/advtop20/grid/CountRegions2.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.grid; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | public class CountRegions2 { 6 | 7 | public static void print(int[][] in) { 8 | for(int[] tmp:in) { 9 | System.out.println(Arrays.toString(tmp)); 10 | } 11 | } 12 | private static void connect(DisjointSet2 dset, int[][] in, int i1, int j1, int i2, int j2) { 13 | int n = in.length; 14 | if(i2 < 0 || j2 < 0 || in[i2][j2] == 0) return; 15 | dset.union(i1*n+j1, i2*n+j2); 16 | } 17 | public static int countRegions(int[][] in) { 18 | DisjointSet2 dset = new DisjointSet2(in); 19 | dset.display(); 20 | for(int i = 0; i < in.length; ++i) { 21 | for(int j = 0; j < in.length; ++j) { 22 | if(in[i][j] == 1) { 23 | connect(dset, in, i, j, i-1, j); 24 | connect(dset, in, i, j, i, j-1); 25 | } 26 | } 27 | } 28 | return dset.getNumSets(); 29 | } 30 | 31 | public static void main(String[] args) { 32 | int n = Integer.parseInt(args[0]); 33 | int[][] in = new int[n][n]; 34 | Random r = new Random(100); 35 | for(int k = 1; k <= 2*n; ++k) { 36 | int ri = r.nextInt(n); 37 | int rj = r.nextInt(n); 38 | in[ri][rj] = 1; 39 | } 40 | print(in); 41 | System.out.println(countRegions(in)); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/traversal/Bipartitionable.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | public class Bipartitionable { 4 | 5 | private static boolean auxBipartite(int u, int[][] in, int[] visit, int groupid) { 6 | visit[u] = groupid; 7 | for(int v = 0; v < in.length; ++v) { 8 | if(in[u][v] == 1) { 9 | if(visit[v] == 0) { //forward edge 10 | if(auxBipartite(v, in, visit, 3-groupid)) return true; 11 | } 12 | else { //back edge 13 | if(visit[u] == visit[v]) return true; 14 | } 15 | } 16 | } 17 | return false; 18 | } 19 | //TC:O(V ^ 2) SC:O(V) 20 | public static boolean isBipartite(int[][] in) { 21 | int[] visit = new int[in.length]; 22 | for(int u = 0; u < in.length; ++u) { 23 | if(visit[u] == 0) { 24 | if(auxBipartite(u, in, visit, 1)) return false; 25 | } 26 | } 27 | System.out.print("Partition1:"); 28 | for(int i = 0; i < visit.length; ++i) 29 | if(visit[i] == 1) System.out.print(i+" "); 30 | System.out.print("Partition2:"); 31 | for(int i = 0; i < visit.length; ++i) 32 | if(visit[i] == 2) System.out.print(i+" "); 33 | return true; 34 | } 35 | public static void main(String[] args) { 36 | int n = Integer.parseInt(args[0]); 37 | int[][] in = GraphUtils.randomGraph(n); 38 | GraphUtils.printGraph(in); 39 | System.out.println(isBipartite(in)); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/src/com/alg/advtop20/graphs/traversal/Bipartitionable.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | public class Bipartitionable { 4 | 5 | private static boolean auxBipartite(int u, int[][] in, int[] visit, int groupid) { 6 | visit[u] = groupid; 7 | for(int v = 0; v < in.length; ++v) { 8 | if(in[u][v] == 1) { 9 | if(visit[v] == 0) { //forward edge 10 | if(auxBipartite(v, in, visit, 3-groupid)) return true; 11 | } 12 | else { //back edge 13 | if(visit[u] == visit[v]) return true; 14 | } 15 | } 16 | } 17 | return false; 18 | } 19 | //TC:O(V ^ 2) SC:O(V) 20 | public static boolean isBipartite(int[][] in) { 21 | int[] visit = new int[in.length]; 22 | for(int u = 0; u < in.length; ++u) { 23 | if(visit[u] == 0) { 24 | if(auxBipartite(u, in, visit, 1)) return false; 25 | } 26 | } 27 | System.out.print("Partition1:"); 28 | for(int i = 0; i < visit.length; ++i) 29 | if(visit[i] == 1) System.out.print(i+" "); 30 | System.out.print("Partition2:"); 31 | for(int i = 0; i < visit.length; ++i) 32 | if(visit[i] == 2) System.out.print(i+" "); 33 | return true; 34 | } 35 | public static void main(String[] args) { 36 | int n = Integer.parseInt(args[0]); 37 | int[][] in = GraphUtils.randomGraph(n); 38 | GraphUtils.printGraph(in); 39 | System.out.println(isBipartite(in)); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /2017-may/1.tree problems/src/com/alg/top20/adv/TreeTraversal.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.adv; 2 | public class TreeTraversal { 3 | 4 | public static void preorder(TreeNode root) { 5 | while (root != null) { 6 | if (root.left == null) { 7 | System.out.println(root.data); 8 | root = root.right; 9 | } else { 10 | TreeNode tmp = root.left; 11 | while (tmp.right != null && tmp.right != root) 12 | tmp = tmp.right; 13 | if (tmp.right == null) { 14 | System.out.println(root.data); 15 | tmp.right = root; 16 | root = root.left; 17 | } else { 18 | tmp.right = null; 19 | root = root.right; 20 | } 21 | } 22 | } 23 | } 24 | 25 | public static void inorder(TreeNode root) { 26 | while (root != null) { 27 | if (root.left == null) { 28 | System.out.println(root.data); 29 | root = root.right; 30 | } else { 31 | TreeNode tmp = root.left; 32 | while (tmp.right != null && tmp.right != root) 33 | tmp = tmp.right; 34 | if (tmp.right == null) { 35 | tmp.right = root; 36 | root = root.left; 37 | } else { 38 | System.out.println(root.data); 39 | tmp.right = null; 40 | root = root.right; 41 | } 42 | } 43 | } 44 | } 45 | 46 | public static void main(String[] args) { 47 | int n = Integer.parseInt(args[0]); 48 | TreeNode root = BinaryTreeUtils.createBinaryTree(n); 49 | BinaryTreeUtils.displayTree2(root); 50 | preorder(root); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /2018-aug/3.graph-problems/src/com/alg/advtop20/graphs/traversal/bipartionable/Bipartitionable.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal.bipartionable; 2 | 3 | import com.alg.advtop20.graphs.GraphUtils; 4 | 5 | public class Bipartitionable { 6 | 7 | private static boolean auxBipartite(int u, int[][] in, int[] visit, int groupid) { 8 | visit[u] = groupid; 9 | for(int v = 0; v < in.length; ++v) { 10 | if(in[u][v] == 1) { 11 | if(visit[v] == 0) { //forward edge 12 | if(auxBipartite(v, in, visit, 3-groupid)) return true; 13 | } 14 | else { //back edge 15 | if(visit[u] == visit[v]) return true; 16 | } 17 | } 18 | } 19 | return false; 20 | } 21 | //TC:O(V ^ 2) SC:O(V) 22 | public static boolean isBipartite(int[][] in) { 23 | int[] visit = new int[in.length]; 24 | for(int u = 0; u < in.length; ++u) { 25 | if(visit[u] == 0) { 26 | if(auxBipartite(u, in, visit, 1)) return false; 27 | } 28 | } 29 | System.out.print("Partition1:"); 30 | for(int i = 0; i < visit.length; ++i) 31 | if(visit[i] == 1) System.out.print(i+" "); 32 | System.out.print("Partition2:"); 33 | for(int i = 0; i < visit.length; ++i) 34 | if(visit[i] == 2) System.out.print(i+" "); 35 | return true; 36 | } 37 | public static void main(String[] args) { 38 | int n = Integer.parseInt(args[0]); 39 | int[][] in = GraphUtils.randomGraph(n); 40 | GraphUtils.printGraph(in); 41 | System.out.println(isBipartite(in)); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /2017-may/1.tree problems/src/com/alg/top20/adv/BSTCounting.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.adv; 2 | 3 | public class BSTCounting { 4 | 5 | //TC:O(c ^ n) SC:O(n) 6 | public static long countBST1(int n) { 7 | if(n <= 1) return 1; 8 | int count = 0; 9 | for(int i = 1; i <= n; ++i) { 10 | count += (countBST1(i-1) * countBST1(n-i)); 11 | } 12 | return count; 13 | } 14 | 15 | //TC:O(n ^ 2) SC:O(n) ~ n + n 16 | public static long countBST2(int n) { 17 | long[] mem = new long[n+1]; 18 | auxCountBST2(n, mem); 19 | return mem[n]; 20 | } 21 | public static long auxCountBST2(int n, long[] mem) { 22 | if(n <= 1) return 1; 23 | int count = 0; 24 | for(int i = 1; i <= n; ++i) { 25 | long left = mem[i-1] != 0?mem[i-1]: auxCountBST2(i-1, mem); 26 | long right = mem[n-i] != 0?mem[n-i]: auxCountBST2(n-i, mem); 27 | count += (left * right); 28 | } 29 | return mem[n] = count; 30 | } 31 | 32 | //TC:O(n ^ 2) SC:O(n) ~ n 33 | public static long countBST3(int n) { 34 | long[] mem = new long[n+1]; 35 | mem[0] = mem[1] = 1; 36 | for(int i = 2 ; i <= n; ++i) { 37 | int count = 0; 38 | for(int j = 1; j <= i; ++j) { 39 | count += (mem[j-1] * mem[i-j]); 40 | } 41 | mem[i] = count; 42 | } 43 | return mem[n]; 44 | } 45 | public static void main(String[] args) { 46 | int n = Integer.parseInt(args[0]); 47 | //System.out.println(countBST1(n)); 48 | //System.out.println(countBST2(n)); 49 | System.out.println(countBST3(n)); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/disjointset/WeightedUnionPathCompressionDS.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph.disjointset; 2 | 3 | import java.util.Arrays; 4 | 5 | public class WeightedUnionPathCompressionDS implements IDisjointSet { 6 | private int size; 7 | private int[] parent; 8 | private int[] weights; 9 | 10 | public WeightedUnionPathCompressionDS(int n) { 11 | parent = new int[n]; 12 | weights = new int[n]; 13 | for (int i = 0; i < n; ++i) { 14 | parent[i] = i; 15 | weights[i] = 1; 16 | } 17 | size = n; 18 | } 19 | 20 | @Override 21 | public int find(int x) { 22 | int current = x; 23 | while (parent[current] != current) 24 | current = parent[current]; 25 | while (parent[x] != x) { 26 | int tmp = parent[x]; 27 | parent[x] = current; 28 | x = tmp; 29 | } 30 | return current; 31 | } 32 | 33 | @Override 34 | public void union(int x, int y) { 35 | int idx = find(x); 36 | int idy = find(y); 37 | if (idx == idy) 38 | return; 39 | --size; 40 | if (weights[idx] > weights[idy]) { 41 | parent[idy] = idx; 42 | weights[idx] += weights[idy]; 43 | } else { 44 | parent[idx] = idy; 45 | weights[idy] += weights[idx]; 46 | } 47 | } 48 | 49 | @Override 50 | public void display() { 51 | System.out.println(Arrays.toString(parent)); 52 | System.out.println(Arrays.toString(weights)); 53 | } 54 | 55 | @Override 56 | public int size() { 57 | return size; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/grid-problems/src/com/alg/advtop20/grid/CountRegions.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.grid; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | public class CountRegions { 7 | 8 | private static void auxRegions(int i, int j, int[][] in, boolean[][] visit) { 9 | if(i < 0 || i >= in.length || j < 0 || j >= in.length) return; 10 | if(in[i][j] == 0 || visit[i][j] == true) return; 11 | visit[i][j] = true; 12 | auxRegions(i, j-1, in, visit); 13 | auxRegions(i, j+1, in, visit); 14 | auxRegions(i-1, j, in, visit); 15 | auxRegions(i+1, j, in, visit); 16 | } 17 | public static int countRegions(int[][] in) { 18 | int count = 0; 19 | boolean[][] visit = new boolean[in.length][in.length]; 20 | for(int i = 0; i < in.length; ++i) { 21 | for(int j = 0; j < in.length; ++j) { 22 | if(in[i][j] == 1 && visit[i][j] == false) { 23 | ++count; 24 | auxRegions(i, j, in, visit); 25 | } 26 | } 27 | } 28 | return count; 29 | } 30 | 31 | public static void print(int[][] in) { 32 | for(int[] tmp:in) { 33 | System.out.println(Arrays.toString(tmp)); 34 | } 35 | } 36 | public static void main(String[] args) { 37 | int n = Integer.parseInt(args[0]); 38 | int[][] in = new int[n][n]; 39 | Random r = new Random(100); 40 | for(int k = 1; k <= 2*n; ++k) { 41 | int ri = r.nextInt(n); 42 | int rj = r.nextInt(n); 43 | in[ri][rj] = 1; 44 | } 45 | print(in); 46 | System.out.println(countRegions(in)); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/grid-problems/src/com/alg/advtop20/grid/CountRegions1.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.grid; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | public class CountRegions1 { 7 | 8 | private static void auxRegions(int i, int j, int[][] in, boolean[][] visit) { 9 | if(i < 0 || i >= in.length || j < 0 || j >= in.length) return; 10 | if(in[i][j] == 0 || visit[i][j] == true) return; 11 | visit[i][j] = true; 12 | auxRegions(i, j-1, in, visit); 13 | auxRegions(i, j+1, in, visit); 14 | auxRegions(i-1, j, in, visit); 15 | auxRegions(i+1, j, in, visit); 16 | } 17 | public static int countRegions(int[][] in) { 18 | int count = 0; 19 | boolean[][] visit = new boolean[in.length][in.length]; 20 | for(int i = 0; i < in.length; ++i) { 21 | for(int j = 0; j < in.length; ++j) { 22 | if(in[i][j] == 1 && visit[i][j] == false) { 23 | ++count; 24 | auxRegions(i, j, in, visit); 25 | } 26 | } 27 | } 28 | return count; 29 | } 30 | 31 | public static void print(int[][] in) { 32 | for(int[] tmp:in) { 33 | System.out.println(Arrays.toString(tmp)); 34 | } 35 | } 36 | public static void main(String[] args) { 37 | int n = Integer.parseInt(args[0]); 38 | int[][] in = new int[n][n]; 39 | Random r = new Random(100); 40 | for(int k = 1; k <= 2*n; ++k) { 41 | int ri = r.nextInt(n); 42 | int rj = r.nextInt(n); 43 | in[ri][rj] = 1; 44 | } 45 | print(in); 46 | System.out.println(countRegions(in)); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/OddLengthCycle.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph; 2 | 3 | public class OddLengthCycle { 4 | // TC:O(n ^ 2) SC:O(n) 5 | public static boolean hasOddCycle1(int[][] in) { 6 | int[] visit = new int[in.length]; 7 | for (int u = 0; u < in.length; ++u) { 8 | if (visit[u] == 0) { 9 | if (dfs(u, u, 1, in, visit)) 10 | return true; 11 | } 12 | } 13 | System.out.println("partition1:"); 14 | for(int u = 0; u < in.length; ++u) { 15 | if(visit[u] == 1) 16 | System.out.print(u +","); 17 | } 18 | System.out.println(); 19 | System.out.println("partition2:"); 20 | for(int u = 0; u < in.length; ++u) { 21 | if(visit[u] == 2) 22 | System.out.print(u +","); 23 | } 24 | System.out.println(); 25 | return false; 26 | } 27 | 28 | private static boolean dfs(int u, int parent, int color, int[][] in, int[] visit) { 29 | visit[u] = color; 30 | for (int v = 0; v < in.length; ++v) { 31 | if (in[u][v] == 1) { 32 | if (visit[v] == 0) { //forward edge 33 | if (dfs(v, u, color==1?2:1, in, visit)) 34 | return true; 35 | } else { //back edge 36 | if (v != parent && visit[u] == visit[v]) 37 | return true; 38 | } 39 | } 40 | } 41 | return false; 42 | } 43 | 44 | public static void main(String[] args) { 45 | int n = Integer.parseInt(args[0]); 46 | int[][] in = GraphUtils.undirectedRandomGraph(n); 47 | GraphUtils.display(in); 48 | System.out.println(hasOddCycle1(in)); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /2017-may/4.string problems/src/com/alg/top20/adv/strings/EditDistance.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.adv.strings; 2 | 3 | public class EditDistance { 4 | 5 | //TC:O(3 ^ m+n) SC:O(m+n) 6 | public static int editDistance1(String s1, String s2) { 7 | return auxDistance1(s1.length(), s2.length(), s1, s2); 8 | } 9 | private static int auxDistance1(int i, int j, String s1, String s2) { 10 | if(i == 0) return j; 11 | if(j == 0) return i; 12 | if(s1.charAt(i-1) == s2.charAt(j-1)) 13 | return auxDistance1(i-1, j-1, s1, s2); 14 | else { 15 | int icost = auxDistance1(i, j-1, s1, s2); 16 | int rcost = auxDistance1(i-1, j-1, s1, s2); 17 | int dcost = auxDistance1(i-1, j, s1, s2); 18 | return Math.min(icost, Math.min(rcost, dcost)) + 1; 19 | } 20 | } 21 | 22 | //TC:O(mn) SC:O(m+n) 23 | public static int editDistance2(String s1, String s2) { 24 | int[][] mem = new int[s1.length()+1][s2.length()+1]; 25 | for(int i = 0; i <= s1.length(); ++i) 26 | mem[i][0] = i; 27 | for(int j = 1; j <= s2.length(); ++j) 28 | mem[0][j] = j; 29 | for(int i = 1; i <= s1.length(); ++i) { 30 | for(int j = 1; j <= s2.length();++j) { 31 | if(s1.charAt(i-1) == s2.charAt(j-1)) 32 | mem[i][j] = mem[i-1][j-1]; 33 | else { 34 | mem[i][j] = Math.min(mem[i][j-1], Math.min(mem[i-1][j-1], mem[i-1][j])) + 1; 35 | } 36 | } 37 | } 38 | return mem[s1.length()][s2.length()]; 39 | } 40 | public static void main(String[] args) { 41 | //System.out.println(editDistance1(args[0], args[1])); 42 | System.out.println(editDistance2(args[0], args[1])); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/BSTCount.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.advdp; 2 | 3 | public class BSTCount { 4 | 5 | public static int bstCount1(int n) { 6 | if (n <= 1) 7 | return 1; 8 | int count = 0; 9 | for (int k = 1; k <= n; ++k) { 10 | int leftCount = bstCount1(k - 1); 11 | int rightCount = bstCount1(n - k); 12 | count += (leftCount * rightCount); 13 | } 14 | return count; 15 | } 16 | 17 | public static int bstCount21(int n) { 18 | int[] mem = new int[n + 1]; 19 | auxCount21(n, mem); 20 | return mem[n]; 21 | } 22 | 23 | private static int auxCount21(int i, int[] mem) { 24 | if (i <= 1) 25 | return 1; 26 | if (mem[i] != 0) 27 | return mem[i]; 28 | int count = 0; 29 | for (int k = 1; k <= i; ++k) { 30 | int leftCount = auxCount21(k - 1, mem); 31 | int rightCount = auxCount21(i - k, mem); 32 | count += (leftCount * rightCount); 33 | } 34 | mem[i] = count; 35 | return count; 36 | } 37 | 38 | public static int bstCount22(int n) { 39 | int[] mem = new int[n + 1]; 40 | mem[0] = mem[1] = 1; 41 | for (int i = 2; i <= n; ++i) { 42 | int count = 0; 43 | for (int k = 1; k <= i; ++k) { 44 | int leftCount = mem[k - 1]; 45 | int rightCount = mem[i - k]; 46 | count += (leftCount * rightCount); 47 | } 48 | mem[i] = count; 49 | } 50 | 51 | return mem[n]; 52 | } 53 | 54 | public static void main(String[] args) { 55 | int n = Integer.parseInt(args[0]); 56 | //System.out.println(bstCount21(n)); 57 | System.out.println(bstCount22(n)); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/dp1/BSTCount.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp1; 2 | 3 | public class BSTCount { 4 | 5 | public static int bstCount1(int n) { 6 | if (n <= 1) 7 | return 1; 8 | int count = 0; 9 | for (int k = 1; k <= n; ++k) { 10 | int leftCount = bstCount1(k - 1); 11 | int rightCount = bstCount1(n - k); 12 | count += (leftCount * rightCount); 13 | } 14 | return count; 15 | } 16 | 17 | public static int bstCount21(int n) { 18 | int[] mem = new int[n + 1]; 19 | auxCount21(n, mem); 20 | return mem[n]; 21 | } 22 | 23 | private static int auxCount21(int i, int[] mem) { 24 | if (i <= 1) 25 | return 1; 26 | if (mem[i] != 0) 27 | return mem[i]; 28 | int count = 0; 29 | for (int k = 1; k <= i; ++k) { 30 | int leftCount = auxCount21(k - 1, mem); 31 | int rightCount = auxCount21(i - k, mem); 32 | count += (leftCount * rightCount); 33 | } 34 | mem[i] = count; 35 | return count; 36 | } 37 | 38 | public static int bstCount22(int n) { 39 | int[] mem = new int[n + 1]; 40 | mem[0] = mem[1] = 1; 41 | for (int i = 2; i <= n; ++i) { 42 | int count = 0; 43 | for (int k = 1; k <= i; ++k) { 44 | int leftCount = mem[k - 1]; 45 | int rightCount = mem[i - k]; 46 | count += (leftCount * rightCount); 47 | } 48 | mem[i] = count; 49 | } 50 | 51 | return mem[n]; 52 | } 53 | 54 | public static void main(String[] args) { 55 | int n = Integer.parseInt(args[0]); 56 | //System.out.println(bstCount21(n)); 57 | System.out.println(bstCount22(n)); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/traversal/CycleDetection.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | 4 | public class CycleDetection { 5 | 6 | private static boolean dfs(int u, int parent, int[][] in, boolean[] visit) { 7 | visit[u] = true; 8 | for(int v = 0; v < in.length; ++v) { 9 | if(in[u][v] == 1){ 10 | if(visit[v] == false) { //forward edge 11 | if(dfs(v, u, in, visit)) return true; 12 | } 13 | else { //back edge 14 | if(parent != v) return true; 15 | } 16 | } 17 | } 18 | return false; 19 | } 20 | //TC:O(V ^ 2) SC:O(V) 21 | public static boolean hasCycle1(int[][] in) { 22 | boolean[] visit = new boolean[in.length]; 23 | for(int u = 0; u < in.length; ++u) { 24 | if(visit[u] == false) { 25 | if(dfs(u, u, in, visit)) return true; 26 | } 27 | } 28 | return false; 29 | } 30 | 31 | public static boolean hasCycle2(int[][] in) { 32 | DisjointSet dset = new DisjointSet(in.length); 33 | for(int i = 1; i < in.length; ++i) { 34 | for(int j = 0; j < i; ++j) { 35 | if(in[i][j] == 1) { 36 | //is i and j are connected previously? 37 | if(dset.find(i) != dset.find(j)) 38 | dset.union(i, j); 39 | else return true; 40 | } 41 | } 42 | } 43 | return false; 44 | } 45 | public static void main(String[] args) { 46 | int n = Integer.parseInt(args[0]); 47 | int[][] in = GraphUtils.randomGraph(n); 48 | GraphUtils.printGraph(in); 49 | System.out.println(hasCycle2(in)); 50 | in = GraphUtils.completeGraph(n); 51 | GraphUtils.printGraph(in); 52 | System.out.println(hasCycle2(in)); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/src/com/alg/advtop20/graphs/traversal/CycleDetection.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | 4 | public class CycleDetection { 5 | 6 | private static boolean dfs(int u, int parent, int[][] in, boolean[] visit) { 7 | visit[u] = true; 8 | for(int v = 0; v < in.length; ++v) { 9 | if(in[u][v] == 1){ 10 | if(visit[v] == false) { //forward edge 11 | if(dfs(v, u, in, visit)) return true; 12 | } 13 | else { //back edge 14 | if(parent != v) return true; 15 | } 16 | } 17 | } 18 | return false; 19 | } 20 | //TC:O(V ^ 2) SC:O(V) 21 | public static boolean hasCycle1(int[][] in) { 22 | boolean[] visit = new boolean[in.length]; 23 | for(int u = 0; u < in.length; ++u) { 24 | if(visit[u] == false) { 25 | if(dfs(u, u, in, visit)) return true; 26 | } 27 | } 28 | return false; 29 | } 30 | 31 | public static boolean hasCycle2(int[][] in) { 32 | DisjointSet dset = new DisjointSet(in.length); 33 | for(int i = 1; i < in.length; ++i) { 34 | for(int j = 0; j < i; ++j) { 35 | if(in[i][j] == 1) { 36 | //is i and j are connected previously? 37 | if(dset.find(i) != dset.find(j)) 38 | dset.union(i, j); 39 | else return true; 40 | } 41 | } 42 | } 43 | return false; 44 | } 45 | public static void main(String[] args) { 46 | int n = Integer.parseInt(args[0]); 47 | int[][] in = GraphUtils.randomGraph(n); 48 | GraphUtils.printGraph(in); 49 | System.out.println(hasCycle2(in)); 50 | in = GraphUtils.completeGraph(n); 51 | GraphUtils.printGraph(in); 52 | System.out.println(hasCycle2(in)); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /2018-aug/3.graph-problems/src/com/alg/advtop20/graphs/traversal/cycledetect/CycleDetection.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal.cycledetect; 2 | 3 | import com.alg.advtop20.graphs.GraphUtils; 4 | 5 | 6 | public class CycleDetection { 7 | 8 | private static boolean dfs(int u, int parent, int[][] in, boolean[] visit) { 9 | visit[u] = true; 10 | for(int v = 0; v < in.length; ++v) { 11 | if(in[u][v] == 1){ 12 | if(visit[v] == false) { //forward edge 13 | if(dfs(v, u, in, visit)) return true; 14 | } 15 | else { //back edge 16 | if(parent != v) return true; 17 | } 18 | } 19 | } 20 | return false; 21 | } 22 | //TC:O(V ^ 2) SC:O(V) 23 | public static boolean hasCycle1(int[][] in) { 24 | boolean[] visit = new boolean[in.length]; 25 | for(int u = 0; u < in.length; ++u) { 26 | if(visit[u] == false) { 27 | if(dfs(u, u, in, visit)) return true; 28 | } 29 | } 30 | return false; 31 | } 32 | 33 | public static boolean hasCycle2(int[][] in) { 34 | DisjointSet dset = new DisjointSet(in.length); 35 | for(int i = 1; i < in.length; ++i) { 36 | for(int j = 0; j < i; ++j) { 37 | if(in[i][j] == 1) { 38 | //is i and j are connected previously? 39 | if(dset.find(i) != dset.find(j)) 40 | dset.union(i, j); 41 | else return true; 42 | } 43 | } 44 | } 45 | return false; 46 | } 47 | public static void main(String[] args) { 48 | int n = Integer.parseInt(args[0]); 49 | int[][] in = GraphUtils.randomGraph(n); 50 | GraphUtils.printGraph(in); 51 | System.out.println(hasCycle2(in)); 52 | in = GraphUtils.completeGraph(n); 53 | GraphUtils.printGraph(in); 54 | System.out.println(hasCycle2(in)); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/segmentree/SeqSegmentTree.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.segmentree; 2 | 3 | import java.util.Arrays; 4 | 5 | public class SeqSegmentTree implements ISegmentTree { 6 | private int[] in; 7 | private int[] segment_tree; 8 | 9 | // O(n) 10 | public SeqSegmentTree(int[] in) { 11 | this.in = in; 12 | this.segment_tree = new int[2 * in.length - 1]; 13 | for (int i = 0; i < in.length; ++i) 14 | segment_tree[i + in.length - 1] = in[i]; 15 | for (int i = in.length - 2; i >= 0; --i) 16 | segment_tree[i] = segment_tree[2 * i + 1] + segment_tree[2 * i + 2]; 17 | } 18 | 19 | // O(log n) 20 | public void update(int i, int x) { 21 | in[i] = x; 22 | int current = i + in.length - 1; 23 | segment_tree[current] = x; 24 | while (current > 0) { 25 | if (current % 2 != 0) 26 | segment_tree[(current - 1) / 2] = segment_tree[current] + segment_tree[current + 1]; 27 | else 28 | segment_tree[(current - 1) / 2] = segment_tree[current] + segment_tree[current - 1]; 29 | current = (current - 1) / 2; 30 | } 31 | } 32 | 33 | // O(log n) 34 | public int rangeSum(int i, int j) { 35 | i = i + in.length - 1; 36 | j = j + in.length - 1; 37 | int sum = 0; 38 | while (i <= j) { 39 | if (i % 2 == 0) { 40 | sum += segment_tree[i]; 41 | ++i; 42 | } 43 | if (j % 2 == 1) { 44 | sum += segment_tree[j]; 45 | --j; 46 | } 47 | if (i > j) 48 | break; 49 | i = (i - 1) / 2; 50 | j = (j - 1) / 2; 51 | } 52 | return sum; 53 | } 54 | 55 | public void display() { 56 | System.out.println(Arrays.toString(in)); 57 | System.out.println(Arrays.toString(segment_tree)); 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/traversal/GraphUtils.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | public class GraphUtils { 7 | 8 | public static void printGraph(int[][] in) { 9 | for(int[] tmp:in) { 10 | System.out.println(Arrays.toString(tmp)); 11 | } 12 | } 13 | 14 | public static int[][] randomGraph(int n) { 15 | int[][] in = new int[n][n]; 16 | Random r = new Random(100); 17 | for(int k = 1; k <= n; ++k) { 18 | int ri = r.nextInt(n); 19 | int rj = r.nextInt(n); 20 | if(ri == rj) continue; 21 | in[ri][rj] = 1; 22 | in[rj][ri] = 1; 23 | } 24 | return in; 25 | } 26 | 27 | public static int[][] completeGraph(int n) { 28 | int[][] in = new int[n][n]; 29 | for(int i = 0; i < n; ++i) { 30 | for(int j = i+1; j < n; ++j) { 31 | in[i][j] = 1; 32 | in[j][i] = 1; 33 | } 34 | } 35 | return in; 36 | } 37 | 38 | public static int[][] convertToGraph(int n, int[][] input) { 39 | int[][] in = new int[n][n]; 40 | for(int[] tmp:input) { 41 | in[tmp[0]][tmp[1]] = 1; 42 | in[tmp[1]][tmp[0]] = 1; 43 | } 44 | return in; 45 | } 46 | 47 | public static int[][] randomDirectedGraph(int n) { 48 | int[][] in = new int[n][n]; 49 | Random r = new Random(100); 50 | for(int k = 1; k <= n; ++k) { 51 | int ri = r.nextInt(n); 52 | int rj = r.nextInt(n); 53 | if(ri == rj) continue; 54 | in[ri][rj] = 1; 55 | } 56 | return in; 57 | } 58 | public static int[][] completeDirectedGraph(int n) { 59 | int[][] in = new int[n][n]; 60 | for(int i = 0; i < n; ++i) { 61 | for(int j = i+1; j < n; ++j) { 62 | in[i][j] = 1; 63 | } 64 | } 65 | return in; 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /2018-aug/2.advanced-dp problems/src/com/alg/advtop20/dp/StringInterleaving.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp; 2 | 3 | public class StringInterleaving { 4 | 5 | public static boolean isInterleave1(String s1, String s2, String s3) { 6 | return auxInterleave1(s1.length(), s2.length(), s1, s2, s3); 7 | } 8 | private static boolean auxInterleave1(int i, int j, String s1, String s2, String s3) { 9 | if(i == 0 && j == 0) return true; 10 | if(i == 0 && j != 0) return s3.substring(0, j).equals(s2.substring(0, j)); 11 | if(j == 0 && i != 0) return s3.substring(0, i).equals(s1.substring(0, i)); 12 | if(s1.charAt(i-1) == s3.charAt(i+j-1)) 13 | if(auxInterleave1(i-1, j, s1, s2, s3)) return true; 14 | if(s2.charAt(j-1) == s3.charAt(i+j-1)) 15 | return auxInterleave1(i, j-1, s1, s2, s3); 16 | return false; 17 | } 18 | 19 | public static boolean isInterleave2(String s1, String s2, String s3) { 20 | boolean[][] mem = new boolean[s1.length()+1][s2.length()+1]; 21 | mem[0][0] = true; 22 | for(int i = 1; i <= s1.length(); ++i) 23 | mem[i][0] = s3.substring(0, i).equals(s1.substring(0, i)); 24 | for(int j = 1; j <= s2.length(); ++j) 25 | mem[0][j] = s3.substring(0, j).equals(s2.substring(0, j)); 26 | for(int i = 1; i <= s1.length(); ++i) { 27 | for(int j = 1; j <= s2.length(); ++j) { 28 | if(s1.charAt(i-1) == s3.charAt(i+j-1)) { 29 | mem[i][j] = mem[i-1][j]; 30 | if(mem[i][j] == true) continue; 31 | } 32 | if(s2.charAt(j-1) == s3.charAt(i+j-1)) 33 | mem[i][j] = mem[i][j-1]; 34 | mem[i][j] = false; 35 | } 36 | } 37 | return mem[s1.length()][s2.length()]; 38 | } 39 | public static void main(String[] args) { 40 | // TODO Auto-generated method stub 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/src/com/alg/advtop20/graphs/traversal/GraphUtils.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | public class GraphUtils { 7 | 8 | public static void printGraph(int[][] in) { 9 | for(int[] tmp:in) { 10 | System.out.println(Arrays.toString(tmp)); 11 | } 12 | } 13 | 14 | public static int[][] randomGraph(int n) { 15 | int[][] in = new int[n][n]; 16 | Random r = new Random(100); 17 | for(int k = 1; k <= n; ++k) { 18 | int ri = r.nextInt(n); 19 | int rj = r.nextInt(n); 20 | if(ri == rj) continue; 21 | in[ri][rj] = 1; 22 | in[rj][ri] = 1; 23 | } 24 | return in; 25 | } 26 | 27 | public static int[][] completeGraph(int n) { 28 | int[][] in = new int[n][n]; 29 | for(int i = 0; i < n; ++i) { 30 | for(int j = i+1; j < n; ++j) { 31 | in[i][j] = 1; 32 | in[j][i] = 1; 33 | } 34 | } 35 | return in; 36 | } 37 | 38 | public static int[][] convertToGraph(int n, int[][] input) { 39 | int[][] in = new int[n][n]; 40 | for(int[] tmp:input) { 41 | in[tmp[0]][tmp[1]] = 1; 42 | in[tmp[1]][tmp[0]] = 1; 43 | } 44 | return in; 45 | } 46 | 47 | public static int[][] randomDirectedGraph(int n) { 48 | int[][] in = new int[n][n]; 49 | Random r = new Random(100); 50 | for(int k = 1; k <= n; ++k) { 51 | int ri = r.nextInt(n); 52 | int rj = r.nextInt(n); 53 | if(ri == rj) continue; 54 | in[ri][rj] = 1; 55 | } 56 | return in; 57 | } 58 | public static int[][] completeDirectedGraph(int n) { 59 | int[][] in = new int[n][n]; 60 | for(int i = 0; i < n; ++i) { 61 | for(int j = i+1; j < n; ++j) { 62 | in[i][j] = 1; 63 | } 64 | } 65 | return in; 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /2017-may/3.backtracking/src/com/alg/top20/bt/Nqueens.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.bt; 2 | 3 | import java.util.Arrays; 4 | 5 | public class Nqueens { 6 | 7 | //TC:O(n ^ (n+2)) SC:O(n) 8 | public static void nqueens1(int n) { 9 | int[] pos = new int[n]; 10 | auxqueens1(0, n, pos); 11 | } 12 | private static boolean isValid1(int[] pos) { 13 | for(int i = 0; i < pos.length; ++i) { 14 | for(int j = i+1; j < pos.length; ++j) { 15 | if(pos[i] == pos[j] || (Math.abs(i-j) == Math.abs(pos[i]-pos[j]))) 16 | return false; 17 | } 18 | } 19 | return true; 20 | } 21 | private static void auxqueens1(int d, int n, int[] pos) { 22 | if(d == n) { 23 | if(isValid1(pos)) 24 | System.out.println(Arrays.toString(pos)); 25 | return; 26 | } 27 | for(int c = 0; c < n; ++c) { 28 | pos[d] = c; 29 | auxqueens1(d+1, n, pos); 30 | } 31 | } 32 | 33 | //TC:O(?) SC:O(n) 34 | public static void nqueens2(int n) { 35 | int[] pos = new int[n]; 36 | auxqueens2(0, n, pos); 37 | } 38 | private static boolean isValid2(int d, int c, int[] pos) { 39 | //add more heuristics to eliminate more branches 40 | //derive heuristics with experience of solving problem 41 | for(int q = 0; q < d; ++q) { 42 | if(pos[q] == c || (Math.abs(q-d) == Math.abs(pos[q]-c))) 43 | return false; 44 | } 45 | return true; 46 | } 47 | private static void auxqueens2(int d, int n, int[] pos) { 48 | if(d == n) { 49 | System.out.println(Arrays.toString(pos)); 50 | return; 51 | } 52 | for(int c = 0; c < n; ++c) { 53 | //backtrack:conditional branching 54 | if(isValid2(d, c, pos)) { 55 | pos[d] = c; 56 | auxqueens2(d+1, n, pos); 57 | } 58 | } 59 | } 60 | public static void main(String[] args) { 61 | int n = Integer.parseInt(args[0]); 62 | nqueens2(n); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /2017-may/4.string problems/src/com/alg/top20/adv/strings/StringInterleave.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.adv.strings; 2 | 3 | import java.util.Arrays; 4 | 5 | public class StringInterleave { 6 | 7 | private static void display(boolean[][] mem) { 8 | for(int i = 0; i < mem.length; ++i) { 9 | System.out.println(Arrays.toString(mem[i])); 10 | } 11 | } 12 | public static boolean isInterleave1(String s1, String s2, String s3) { 13 | return auxInterleave(0, 0, "", s1, s2, s3 ); 14 | //return true; 15 | } 16 | private static boolean auxInterleave(int i, int j, String res, String s1, String s2, String s3) { 17 | if(i == s1.length()) { 18 | System.out.println(res+s2.substring(j)); 19 | return s3.equals(res+s2.substring(j)); 20 | } 21 | if(j == s2.length()) { 22 | System.out.println(res+s1.substring(i)); 23 | return s3.equals(res+s1.substring(i)); 24 | } 25 | if(auxInterleave(i+1, j, res+s1.charAt(i), s1, s2, s3)) return true; 26 | return auxInterleave(i, j+1, res+s2.charAt(j), s1, s2, s3); 27 | } 28 | 29 | public static boolean isInterleave2(String s1, String s2, String s3) { 30 | int n = s1.length(); 31 | int m = s2.length(); 32 | boolean[][] mem = new boolean[n+1][m+1]; 33 | for(int j = 1; j <= m; ++j) { 34 | mem[0][j] = s2.substring(0,j).equals(s3.substring(0,j)); 35 | } 36 | for(int i = 1; i <= n; ++i) { 37 | mem[i][0] = s1.substring(0,i).equals(s3.substring(0,i)); 38 | } 39 | for(int i = 1; i <= n; ++i) { 40 | for(int j = 1; j <= m; ++j) { 41 | mem[i][j] = ((s1.charAt(i-1) == s3.charAt(i+j-1)) && mem[i-1][j]) || 42 | ((s2.charAt(j-1) == s3.charAt(i+j-1)) && mem[i][j-1]); 43 | } 44 | } 45 | display(mem); 46 | return mem[n][m]; 47 | } 48 | public static void main(String[] args) { 49 | System.out.println(isInterleave2(args[0], args[1], args[2])); 50 | 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/CourseSchedule.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | public class CourseSchedule { 7 | 8 | // TC:O(n ^ 2) 9 | // SC:O(n) 10 | public static void courseSchedule1(int[][] in) { 11 | int[] indegree = new int[in.length]; 12 | for (int i = 0; i < in.length; ++i) { 13 | for (int j = 0; j < in.length; ++j) { 14 | if (in[i][j] == 1) 15 | ++indegree[j]; 16 | } 17 | } 18 | int i, j; 19 | while (true) { 20 | for (i = 0; i < in.length; ++i) { 21 | if (indegree[i] == 0) { 22 | System.out.print(i + "->"); 23 | indegree[i] = -1; 24 | break; 25 | } 26 | } 27 | if (i == in.length) 28 | break; 29 | for (j = 0; j < in.length; ++j) { 30 | if (in[i][j] == 1) 31 | --indegree[j]; 32 | } 33 | } 34 | System.out.println(); 35 | } 36 | 37 | // TC:O(n ^ 2) 38 | // SC:O(n) 39 | public static void courseSchedule2(int[][] in) { 40 | boolean[] visit = new boolean[in.length]; 41 | List list = new LinkedList(); 42 | for (int u = 0; u < in.length; ++u) { 43 | if (visit[u] == false) 44 | dfs(u, in, visit, list); 45 | } 46 | System.out.println(list); 47 | } 48 | 49 | private static void dfs(int u, int[][] in, boolean[] visit, List list) { 50 | visit[u] = true; 51 | for (int v = 0; v < in.length; ++v) { 52 | if (in[u][v] == 1) { 53 | if (visit[v] == false) 54 | dfs(v, in, visit, list); 55 | } 56 | } 57 | list.add(0, u); 58 | } 59 | 60 | public static void main(String[] args) { 61 | int n = Integer.parseInt(args[0]); 62 | int[][] in = GraphUtils.directedCompleteGraph(n); 63 | GraphUtils.display(in); 64 | courseSchedule1(in); 65 | courseSchedule2(in); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/LongIncrSubseq1.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp3; 2 | 3 | public class LongIncrSubseq1 { 4 | 5 | public static int lis1(int[] in) { 6 | int gmax = Integer.MIN_VALUE; 7 | for (int i = 0; i < in.length; ++i) { 8 | MyInteger max = new MyInteger(Integer.MIN_VALUE); 9 | auxlis1(i, 0, max, in); 10 | gmax = Math.max(gmax, max.get()); 11 | } 12 | return gmax; 13 | } 14 | 15 | private static void auxlis1(int i, int csum, MyInteger max, int[] in) { 16 | if (i == in.length - 1) { 17 | max.set(Math.max(max.get(), csum + 1)); 18 | return; 19 | } 20 | for (int j = i + 1; j < in.length; ++j) { 21 | if (in[j] > in[i]) 22 | auxlis1(j, csum + 1, max, in); 23 | } 24 | } 25 | 26 | public static int lis2(int[] in) { 27 | int gmax = Integer.MIN_VALUE; 28 | for (int i = 0; i < in.length; ++i) { 29 | int res = auxlis2(i, in); 30 | gmax = Math.max(gmax, res); 31 | } 32 | return gmax; 33 | } 34 | 35 | private static int auxlis2(int i, int[] in) { 36 | if (i == in.length - 1) 37 | return 1; 38 | int max = Integer.MIN_VALUE; 39 | for (int j = i + 1; j < in.length; ++j) { 40 | if (in[j] > in[i]) { 41 | int res = auxlis2(j, in); 42 | max = Math.max(max, res); 43 | } 44 | } 45 | return max; 46 | } 47 | 48 | public static int lis32(int[] in) { 49 | int gmax = Integer.MIN_VALUE; 50 | int n = in.length; 51 | int[] mem = new int[n]; 52 | mem[n - 1] = 1; 53 | for (int i = n - 2; i >= 0; --i) { 54 | int max = Integer.MIN_VALUE; 55 | for (int j = i + 1; j < in.length; ++j) { 56 | if (in[j] > in[i]) 57 | max = Math.max(max, mem[j]); 58 | } 59 | mem[i] = max; 60 | gmax = Math.max(gmax, max); 61 | } 62 | return gmax; 63 | } 64 | 65 | public static void main(String[] args) { 66 | // TODO Auto-generated method stub 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/dp3/LongIncrSubseq1.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp3; 2 | 3 | public class LongIncrSubseq1 { 4 | 5 | public static int lis1(int[] in) { 6 | int gmax = Integer.MIN_VALUE; 7 | for (int i = 0; i < in.length; ++i) { 8 | MyInteger max = new MyInteger(Integer.MIN_VALUE); 9 | auxlis1(i, 0, max, in); 10 | gmax = Math.max(gmax, max.get()); 11 | } 12 | return gmax; 13 | } 14 | 15 | private static void auxlis1(int i, int csum, MyInteger max, int[] in) { 16 | if (i == in.length - 1) { 17 | max.set(Math.max(max.get(), csum + 1)); 18 | return; 19 | } 20 | for (int j = i + 1; j < in.length; ++j) { 21 | if (in[j] > in[i]) 22 | auxlis1(j, csum + 1, max, in); 23 | } 24 | } 25 | 26 | public static int lis2(int[] in) { 27 | int gmax = Integer.MIN_VALUE; 28 | for (int i = 0; i < in.length; ++i) { 29 | int res = auxlis2(i, in); 30 | gmax = Math.max(gmax, res); 31 | } 32 | return gmax; 33 | } 34 | 35 | private static int auxlis2(int i, int[] in) { 36 | if (i == in.length - 1) 37 | return 1; 38 | int max = Integer.MIN_VALUE; 39 | for (int j = i + 1; j < in.length; ++j) { 40 | if (in[j] > in[i]) { 41 | int res = auxlis2(j, in); 42 | max = Math.max(max, res); 43 | } 44 | } 45 | return max; 46 | } 47 | 48 | public static int lis32(int[] in) { 49 | int gmax = Integer.MIN_VALUE; 50 | int n = in.length; 51 | int[] mem = new int[n]; 52 | mem[n - 1] = 1; 53 | for (int i = n - 2; i >= 0; --i) { 54 | int max = Integer.MIN_VALUE; 55 | for (int j = i + 1; j < in.length; ++j) { 56 | if (in[j] > in[i]) 57 | max = Math.max(max, mem[j]); 58 | } 59 | mem[i] = max; 60 | gmax = Math.max(gmax, max); 61 | } 62 | return gmax; 63 | } 64 | 65 | public static void main(String[] args) { 66 | // TODO Auto-generated method stub 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/SubsetSum.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp2; 2 | 3 | public class SubsetSum { 4 | 5 | private static boolean subsetSum1(int[] in, int s) { 6 | return auxSum1(0, 0, in, s); 7 | } 8 | 9 | private static boolean auxSum1(int i, int csum, int[] in, int s) { 10 | if (i == in.length) 11 | return csum == s; 12 | if(csum > s) return false; 13 | if (auxSum1(i + 1, csum, in, s)) 14 | return true; 15 | return auxSum1(i + 1, csum + in[i], in, s); 16 | } 17 | 18 | private static boolean subsetSum2(int[] in, int s) { 19 | return auxSum2(0, in, s); 20 | } 21 | 22 | private static boolean auxSum2(int i, int[] in, int j) { 23 | if (i == in.length-1) 24 | return in[i] == j; 25 | if (in[i] > j) 26 | return false; 27 | if (auxSum2(i + 1, in, j)) 28 | return true; 29 | return auxSum2(i + 1, in, j - in[i]); 30 | } 31 | 32 | private static boolean subsetSum31(int[] in, int s) { 33 | Boolean[][] mem = new Boolean[in.length][s+1]; 34 | return auxSum31(0, in, s, mem); 35 | } 36 | 37 | private static Boolean auxSum31(int i, int[] in, int j, Boolean[][] mem) { 38 | if (i == in.length-1) 39 | return in[i] == j; 40 | if (in[i] > j) 41 | return false; 42 | if(mem[i][j] != null) return mem[i][j]; 43 | if (auxSum31(i + 1, in, j, mem)) 44 | return mem[i][j] = true; 45 | return mem[i][j] = auxSum31(i + 1, in, j - in[i], mem); 46 | } 47 | 48 | private static boolean subsetSum32(int[] in, int s) { 49 | int n = in.length; 50 | boolean[][] mem = new boolean[n][s+1]; 51 | for(int j = 0; j <= s; ++j) 52 | mem[n-1][j] = (in[n-1] == j); 53 | for(int i = n-2; i >= 0; --i) { 54 | for(int j = 1; j <= s; ++j) { 55 | if(in[i] > j) 56 | mem[i][j] = false; 57 | else 58 | mem[i][j] = mem[i+1][j] || mem[i+1][j-in[i]]; 59 | } 60 | } 61 | return mem[0][s]; 62 | } 63 | 64 | public static void main(String[] args) { 65 | // TODO Auto-generated method stub 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/dp2/SubsetSum.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp2; 2 | 3 | public class SubsetSum { 4 | 5 | private static boolean subsetSum1(int[] in, int s) { 6 | return auxSum1(0, 0, in, s); 7 | } 8 | 9 | private static boolean auxSum1(int i, int csum, int[] in, int s) { 10 | if (i == in.length) 11 | return csum == s; 12 | if(csum > s) return false; 13 | if (auxSum1(i + 1, csum, in, s)) 14 | return true; 15 | return auxSum1(i + 1, csum + in[i], in, s); 16 | } 17 | 18 | private static boolean subsetSum2(int[] in, int s) { 19 | return auxSum2(0, in, s); 20 | } 21 | 22 | private static boolean auxSum2(int i, int[] in, int j) { 23 | if (i == in.length-1) 24 | return in[i] == j; 25 | if (in[i] > j) 26 | return false; 27 | if (auxSum2(i + 1, in, j)) 28 | return true; 29 | return auxSum2(i + 1, in, j - in[i]); 30 | } 31 | 32 | private static boolean subsetSum31(int[] in, int s) { 33 | Boolean[][] mem = new Boolean[in.length][s+1]; 34 | return auxSum31(0, in, s, mem); 35 | } 36 | 37 | private static Boolean auxSum31(int i, int[] in, int j, Boolean[][] mem) { 38 | if (i == in.length-1) 39 | return in[i] == j; 40 | if (in[i] > j) 41 | return false; 42 | if(mem[i][j] != null) return mem[i][j]; 43 | if (auxSum31(i + 1, in, j, mem)) 44 | return mem[i][j] = true; 45 | return mem[i][j] = auxSum31(i + 1, in, j - in[i], mem); 46 | } 47 | 48 | private static boolean subsetSum32(int[] in, int s) { 49 | int n = in.length; 50 | boolean[][] mem = new boolean[n][s+1]; 51 | for(int j = 0; j <= s; ++j) 52 | mem[n-1][j] = (in[n-1] == j); 53 | for(int i = n-2; i >= 0; --i) { 54 | for(int j = 1; j <= s; ++j) { 55 | if(in[i] > j) 56 | mem[i][j] = false; 57 | else 58 | mem[i][j] = mem[i+1][j] || mem[i+1][j-in[i]]; 59 | } 60 | } 61 | return mem[0][s]; 62 | } 63 | 64 | public static void main(String[] args) { 65 | // TODO Auto-generated method stub 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/AllPairsPalCheck.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp1; 2 | 3 | import java.util.Arrays; 4 | 5 | public class AllPairsPalCheck { 6 | 7 | public static void allPairsPalCheck1(String in) { 8 | for (int i = 0; i < in.length(); ++i) { 9 | for (int j = i + 1; j < in.length(); ++j) { 10 | System.out.println(auxPalCheck1(in, i, j)); 11 | } 12 | } 13 | } 14 | 15 | private static boolean auxPalCheck1(String in, int i, int j) { 16 | if (i >= j) 17 | return true; 18 | if (in.charAt(i) == in.charAt(j)) 19 | return auxPalCheck1(in, i + 1, j - 1); 20 | else 21 | return false; 22 | } 23 | 24 | public static void allPairsPalCheck21(String in) { 25 | int[][] mem = new int[in.length()][in.length()]; 26 | for (int i = 0; i < in.length(); ++i) { 27 | for (int j = i + 1; j < in.length(); ++j) { 28 | System.out.println(auxPalCheck21(in, i, j, mem)); 29 | } 30 | } 31 | } 32 | 33 | private static int auxPalCheck21(String in, int i, int j, int[][] mem) { 34 | if (i >= j) 35 | return 1; 36 | if (mem[i][j] != 0) 37 | return mem[i][j]; 38 | if (in.charAt(i) == in.charAt(j)) 39 | return mem[i][j] = auxPalCheck21(in, i + 1, j - 1, mem); 40 | else 41 | return mem[i][j] = -1; 42 | } 43 | 44 | public static void allPairsPalCheck22(String in) { 45 | boolean[][] mem = new boolean[in.length()][in.length()]; 46 | for (int i = 0; i < in.length()-1; ++i) { 47 | mem[i][i] = true; 48 | mem[i+1][i] = true; 49 | } 50 | 51 | for (int i = in.length() - 2; i >= 0; --i) { 52 | for (int j = i + 1; j < in.length(); ++j) { 53 | if (in.charAt(i) == in.charAt(j)) 54 | mem[i][j] = mem[i + 1][j - 1]; 55 | else 56 | mem[i][j] = false; 57 | } 58 | } 59 | for(boolean[] tmp: mem) 60 | System.out.println(Arrays.toString(tmp)); 61 | } 62 | 63 | public static void main(String[] args) { 64 | //allPairsPalCheck1(args[0]); 65 | //System.out.println(); 66 | allPairsPalCheck22(args[0]); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/dp1/AllPairsPalCheck.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp1; 2 | 3 | import java.util.Arrays; 4 | 5 | public class AllPairsPalCheck { 6 | 7 | public static void allPairsPalCheck1(String in) { 8 | for (int i = 0; i < in.length(); ++i) { 9 | for (int j = i + 1; j < in.length(); ++j) { 10 | System.out.println(auxPalCheck1(in, i, j)); 11 | } 12 | } 13 | } 14 | 15 | private static boolean auxPalCheck1(String in, int i, int j) { 16 | if (i >= j) 17 | return true; 18 | if (in.charAt(i) == in.charAt(j)) 19 | return auxPalCheck1(in, i + 1, j - 1); 20 | else 21 | return false; 22 | } 23 | 24 | public static void allPairsPalCheck21(String in) { 25 | int[][] mem = new int[in.length()][in.length()]; 26 | for (int i = 0; i < in.length(); ++i) { 27 | for (int j = i + 1; j < in.length(); ++j) { 28 | System.out.println(auxPalCheck21(in, i, j, mem)); 29 | } 30 | } 31 | } 32 | 33 | private static int auxPalCheck21(String in, int i, int j, int[][] mem) { 34 | if (i >= j) 35 | return 1; 36 | if (mem[i][j] != 0) 37 | return mem[i][j]; 38 | if (in.charAt(i) == in.charAt(j)) 39 | return mem[i][j] = auxPalCheck21(in, i + 1, j - 1, mem); 40 | else 41 | return mem[i][j] = -1; 42 | } 43 | 44 | public static void allPairsPalCheck22(String in) { 45 | boolean[][] mem = new boolean[in.length()][in.length()]; 46 | for (int i = 0; i < in.length()-1; ++i) { 47 | mem[i][i] = true; 48 | mem[i+1][i] = true; 49 | } 50 | 51 | for (int i = in.length() - 2; i >= 0; --i) { 52 | for (int j = i + 1; j < in.length(); ++j) { 53 | if (in.charAt(i) == in.charAt(j)) 54 | mem[i][j] = mem[i + 1][j - 1]; 55 | else 56 | mem[i][j] = false; 57 | } 58 | } 59 | for(boolean[] tmp: mem) 60 | System.out.println(Arrays.toString(tmp)); 61 | } 62 | 63 | public static void main(String[] args) { 64 | //allPairsPalCheck1(args[0]); 65 | //System.out.println(); 66 | allPairsPalCheck22(args[0]); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/rangequery/oned/RangeSum3.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery.oned; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | class SegmentTree { 7 | private int n; 8 | private int[] segment_tree; 9 | 10 | //O(n) 11 | public SegmentTree(int[] in) { 12 | this.n = in.length; 13 | this.segment_tree = new int[2*in.length-1]; 14 | for(int i = 0; i < in.length; ++i) 15 | segment_tree[i+in.length-1] = in[i]; 16 | for(int i = in.length-2; i >= 0; --i) 17 | segment_tree[i] = segment_tree[2*i+1] + segment_tree[2*i+2]; 18 | } 19 | //O(log n) 20 | public void update(int i, int x) { 21 | int current = i + n - 1; 22 | segment_tree[current] = x; 23 | while(current > 0) { 24 | if(current%2 != 0) 25 | segment_tree[(current-1)/2] = segment_tree[current] + segment_tree[current+1]; 26 | else 27 | segment_tree[(current-1)/2] = segment_tree[current] + segment_tree[current-1]; 28 | current = (current-1)/2; 29 | } 30 | } 31 | //O(log n) 32 | public int rangeSum(int i, int j) { 33 | i = i + n - 1; 34 | j = j + n - 1; 35 | int sum = 0; 36 | while(i <= j) { 37 | if(i%2 == 0) { 38 | sum += segment_tree[i]; 39 | if(i == 0) break; 40 | ++i; 41 | } 42 | if(j%2 == 1) { 43 | sum += segment_tree[j]; 44 | --j; 45 | } 46 | i = (i-1)/2; 47 | j = (j-1)/2; 48 | } 49 | return sum; 50 | } 51 | 52 | 53 | public void display() { 54 | for(int i = 0; i < segment_tree.length; ++i) 55 | System.out.print(segment_tree[i]+ " "); 56 | System.out.println(); 57 | } 58 | 59 | public static void main(String[] args) { 60 | int n = Integer.parseInt(args[0]); 61 | int[] in = new int[n]; 62 | Random r = new Random(100); 63 | for(int i = 0; i < n; ++i) 64 | in[i] = r.nextInt(n); 65 | System.out.println(Arrays.toString(in)); 66 | RangeSum3 rs = new RangeSum3(in); 67 | rs.display(); 68 | System.out.println(rs.rangeSum(0, n-1)); 69 | System.out.println(rs.rangeSum(1, n-2)); 70 | rs.update(1, -1); 71 | rs.display(); 72 | System.out.println(rs.rangeSum(0, n-1)); 73 | System.out.println(rs.rangeSum(1, n-2)); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /2017-may/1.tree problems/src/com/alg/top20/adv/BinaryTreeUtils.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.adv; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | import java.util.Random; 6 | 7 | public class BinaryTreeUtils { 8 | 9 | private static TreeNode add(TreeNode root, int data) { 10 | if (root == null) 11 | return new TreeNode(data); 12 | TreeNode current = root, parent = null; 13 | while (current != null) { 14 | parent = current; 15 | if (Math.random() < 0.5) { 16 | if(current.left == null) { 17 | parent.left = new TreeNode(data); 18 | break; 19 | } 20 | current = current.left; 21 | } 22 | else { 23 | if(current.right == null) { 24 | parent.right = new TreeNode(data); 25 | break; 26 | } 27 | current = current.right; 28 | } 29 | } 30 | return root; 31 | } 32 | 33 | public static TreeNode createBinaryTree(int n) { 34 | Random r = new Random(); 35 | TreeNode root = null; 36 | for (int i = 0; i < n; ++i) { 37 | int data = r.nextInt(n) + 1; 38 | root = add(root, data); 39 | } 40 | return root; 41 | } 42 | 43 | public static void displayTree1(TreeNode root) { 44 | Queue q = new LinkedList(); 45 | q.add(root); 46 | q.add(null); 47 | TreeNode dummy = new TreeNode(-1); 48 | while(true) { 49 | TreeNode tmp = q.remove(); 50 | if(tmp == null) { 51 | System.out.println(); 52 | if(! q.isEmpty()) 53 | q.add(null); 54 | else 55 | break; 56 | } else { 57 | System.out.print(tmp.data+ " "); 58 | if(tmp == dummy) continue; 59 | if(tmp.left != null) q.add(tmp.left); 60 | else q.add(dummy); 61 | if(tmp.right != null) q.add(tmp.right); 62 | else q.add(dummy); 63 | } 64 | } 65 | } 66 | 67 | public static void displayTree2(TreeNode root) { 68 | auxDisplay(root, 0); 69 | } 70 | //todo: empty left subtree case 71 | private static void auxDisplay(TreeNode root, int nspaces) { 72 | if(root == null) return; 73 | for(int i = 0; i < nspaces; ++i) 74 | System.out.print(' '); 75 | System.out.println(root.data); 76 | auxDisplay(root.left, nspaces + 4); 77 | auxDisplay(root.right, nspaces + 4); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/rangequery/oned/RangeSum5.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery.oned; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | class FenwickTree { 7 | private int[] in; 8 | private int[] aux; 9 | 10 | //O(n^2) 11 | public FenwickTree(int[] in) { 12 | this.in = in; 13 | aux = new int[in.length]; 14 | aux[0] = in[0]; 15 | for(int i = 1; i < aux.length; i+=2) 16 | aux[i] = in[i]; 17 | for(int i = 2; i < aux.length; i+=2) { 18 | int sum = 0; 19 | int r = getRightmostOne(i); 20 | for(int j = i - (1<>>= 1; 33 | } 34 | return pos; 35 | } 36 | //O(log n) 37 | public void update(int i, int x) { 38 | int old = in[i]; 39 | in[i] = x; 40 | while(i < aux.length) { 41 | aux[i] += (x-old); 42 | i += (i & -i); 43 | } 44 | } 45 | private int cumulativeSum(int i) { 46 | int sum = aux[0]; 47 | while(i > 0) { 48 | sum += aux[i]; 49 | i -= (i & -i); 50 | } 51 | return sum; 52 | } 53 | //O(log n) 54 | public int rangeSum(int i, int j) { 55 | if(i == 0) return cumulativeSum(j); 56 | return cumulativeSum(j) - cumulativeSum(i-1); 57 | } 58 | 59 | public void display() { 60 | System.out.println(Arrays.toString(in)); 61 | System.out.println(Arrays.toString(aux)); 62 | } 63 | } 64 | 65 | public class RangeSum5 { 66 | 67 | public static void main(String[] args) { 68 | int n = Integer.parseInt(args[0]); 69 | int[] in = new int[n]; 70 | Random r = new Random(100); 71 | for(int i = 0; i < n; ++i) 72 | in[i] = r.nextInt(n); 73 | FenwickTree tree = new FenwickTree(in); 74 | tree.display(); 75 | System.out.println(tree.rangeSum(0, n-1)); 76 | System.out.println(tree.rangeSum(1, n-2)); 77 | tree.update(1, -1); 78 | tree.display(); 79 | System.out.println(tree.rangeSum(0, n-1)); 80 | System.out.println(tree.rangeSum(1, n-2)); 81 | tree.update(2, 3); 82 | tree.display(); 83 | System.out.println(tree.rangeSum(0, n-1)); 84 | System.out.println(tree.rangeSum(1, n-2)); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/traversal/CourseSchedule.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | import java.util.Stack; 6 | 7 | public class CourseSchedule { 8 | 9 | //TC:O(V ^ 2) SC:O(V) 10 | public static Queue courseSchedule1(int[][] in) { 11 | int[] indegree = new int[in.length]; 12 | Queue q = new LinkedList(); 13 | for(int i = 0; i < in.length; ++i) { 14 | for(int j = 0; j < in.length; ++j) { 15 | if(in[i][j] == 1) 16 | ++indegree[j]; 17 | } 18 | } 19 | for(int k = 1; k <= in.length; ++k) { 20 | int i; 21 | for(i = 0; i < in.length; ++i) { 22 | if(indegree[i] == 0) { 23 | indegree[i] = -1; 24 | q.add(i); 25 | for(int j = 0; j < in.length; ++j) { 26 | if(in[i][j] == 1) 27 | --indegree[j]; 28 | } 29 | break; 30 | } 31 | } 32 | if(i == in.length) return null; 33 | } 34 | return q; 35 | } 36 | 37 | private static boolean dfs(int u, int[][] in, int[] visit, Stack st) { 38 | visit[u] = 1; 39 | for(int v = 0; v < in.length; ++v) { 40 | if(in[u][v] == 1) { 41 | //forward edge 42 | if(visit[v] == 0) { 43 | if(dfs(v, in, visit, st)) return true; 44 | } else { //cyclic edge 45 | if(visit[v] == 1) return true; 46 | } 47 | } 48 | } 49 | visit[u] = 2; 50 | st.push(u); 51 | return false; 52 | } 53 | //TC:O(V ^ 2) SC:O(V) 54 | public static Stack courseSchedule2(int[][] in) { 55 | int[] visit = new int[in.length]; 56 | Stack st = new Stack(); 57 | for(int u = 0; u < in.length; ++u) { 58 | if(visit[u] == 0) 59 | if(dfs(u, in, visit, st)) return null; 60 | } 61 | return st; 62 | } 63 | public static void main(String[] args) { 64 | int n = Integer.parseInt(args[0]); 65 | int[][] in = GraphUtils.completeDirectedGraph(n); 66 | GraphUtils.printGraph(in); 67 | System.out.println(courseSchedule1(in)); 68 | System.out.println(courseSchedule2(in)); 69 | 70 | System.out.println(); 71 | in = GraphUtils.randomDirectedGraph(n); 72 | GraphUtils.printGraph(in); 73 | System.out.println(courseSchedule1(in)); 74 | System.out.println(courseSchedule2(in)); 75 | 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/src/com/alg/advtop20/graphs/traversal/CourseSchedule.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | import java.util.Stack; 6 | 7 | public class CourseSchedule { 8 | 9 | //TC:O(V ^ 2) SC:O(V) 10 | public static Queue courseSchedule1(int[][] in) { 11 | int[] indegree = new int[in.length]; 12 | Queue q = new LinkedList(); 13 | for(int i = 0; i < in.length; ++i) { 14 | for(int j = 0; j < in.length; ++j) { 15 | if(in[i][j] == 1) 16 | ++indegree[j]; 17 | } 18 | } 19 | for(int k = 1; k <= in.length; ++k) { 20 | int i; 21 | for(i = 0; i < in.length; ++i) { 22 | if(indegree[i] == 0) { 23 | indegree[i] = -1; 24 | q.add(i); 25 | for(int j = 0; j < in.length; ++j) { 26 | if(in[i][j] == 1) 27 | --indegree[j]; 28 | } 29 | break; 30 | } 31 | } 32 | if(i == in.length) return null; 33 | } 34 | return q; 35 | } 36 | 37 | private static boolean dfs(int u, int[][] in, int[] visit, Stack st) { 38 | visit[u] = 1; 39 | for(int v = 0; v < in.length; ++v) { 40 | if(in[u][v] == 1) { 41 | //forward edge 42 | if(visit[v] == 0) { 43 | if(dfs(v, in, visit, st)) return true; 44 | } else { //cyclic edge 45 | if(visit[v] == 1) return true; 46 | } 47 | } 48 | } 49 | visit[u] = 2; 50 | st.push(u); 51 | return false; 52 | } 53 | //TC:O(V ^ 2) SC:O(V) 54 | public static Stack courseSchedule2(int[][] in) { 55 | int[] visit = new int[in.length]; 56 | Stack st = new Stack(); 57 | for(int u = 0; u < in.length; ++u) { 58 | if(visit[u] == 0) 59 | if(dfs(u, in, visit, st)) return null; 60 | } 61 | return st; 62 | } 63 | public static void main(String[] args) { 64 | int n = Integer.parseInt(args[0]); 65 | int[][] in = GraphUtils.completeDirectedGraph(n); 66 | GraphUtils.printGraph(in); 67 | System.out.println(courseSchedule1(in)); 68 | System.out.println(courseSchedule2(in)); 69 | 70 | System.out.println(); 71 | in = GraphUtils.randomDirectedGraph(n); 72 | GraphUtils.printGraph(in); 73 | System.out.println(courseSchedule1(in)); 74 | System.out.println(courseSchedule2(in)); 75 | 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /2017-may/1.tree problems/src/com/alg/top20/adv/MaxSumNoAdjacent.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.adv; 2 | import java.util.HashMap; 3 | 4 | 5 | public class MaxSumNoAdjacent { 6 | 7 | public static long maxSum1(TreeNode root) { 8 | if(root == null) return 0; 9 | if(root.left == null && root.right == null) 10 | return root.data; 11 | long exclusive_profit = maxSum1(root.left) + maxSum1(root.right); 12 | long inclusive_profit = root.data; 13 | TreeNode lc = root.left; 14 | TreeNode rc = root.right; 15 | if(lc != null) { 16 | inclusive_profit += maxSum1(lc.left) + maxSum1(lc.right); 17 | } 18 | if(rc != null) { 19 | inclusive_profit += maxSum1(rc.left) + maxSum1(rc.right); 20 | } 21 | return Math.max(exclusive_profit, inclusive_profit); 22 | } 23 | 24 | //TC:O(n) SC:O(n) 25 | public static long maxSum2(TreeNode root) { 26 | HashMap mem = new HashMap(); 27 | auxSum2(root, mem); 28 | return mem.get(root); 29 | } 30 | 31 | public static 32 | long auxSum2(TreeNode root, HashMap mem) { 33 | if(root == null) return 0; 34 | if(root.left == null && root.right == null) 35 | return root.data; 36 | long exclusive_profit = 0; 37 | exclusive_profit += mem.get(root.left) != null?mem.get(root.left):auxSum2(root.left, mem); 38 | exclusive_profit += mem.get(root.right) != null? mem.get(root.right):auxSum2(root.right, mem); 39 | 40 | long inclusive_profit = root.data; 41 | TreeNode lc = root.left; 42 | TreeNode rc = root.right; 43 | if(lc != null) { 44 | inclusive_profit += mem.get(lc.left)!=null?mem.get(lc.left):auxSum2(lc.left, mem); 45 | inclusive_profit += mem.get(lc.right)!=null?mem.get(lc.right):auxSum2(lc.right, mem); 46 | } 47 | if(rc != null) { 48 | inclusive_profit += mem.get(rc.left)!=null?mem.get(rc.left):auxSum2(rc.left, mem); 49 | inclusive_profit += mem.get(rc.right)!=null?mem.get(rc.right):auxSum2(rc.right, mem); 50 | } 51 | long res = Math.max(exclusive_profit, inclusive_profit); 52 | mem.put(root, res); 53 | return res; 54 | } 55 | public static void main(String[] args) { 56 | int n = Integer.parseInt(args[0]); 57 | TreeNode root = BinaryTreeUtils.createBinaryTree(n); 58 | //BinaryTreeUtils.displayTree2(root); 59 | //System.out.println(maxSum1(root)); 60 | System.out.println(maxSum2(root)); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/CountFriendCircles.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | 6 | import com.alg.advtop20.graph.disjointset.IDisjointSet; 7 | import com.alg.advtop20.graph.disjointset.WeightedUnionDS; 8 | 9 | public class CountFriendCircles { 10 | private static void dfs(int u, int[][] in, boolean[] visit) { 11 | visit[u] = true; 12 | for (int v = 0; v < in.length; ++v) { 13 | if (in[u][v] == 1) { 14 | if (visit[v] == false) 15 | dfs(v, in, visit); 16 | } 17 | } 18 | } 19 | 20 | private static void bfs(int u, int[][] in, boolean[] visit) { 21 | Queue q = new LinkedList(); 22 | q.add(u); 23 | visit[u] = true; 24 | while (!q.isEmpty()) { 25 | u = q.remove(); 26 | for (int v = 0; v < in.length; ++v) { 27 | if (in[u][v] == 1 && visit[v] == false) { 28 | q.add(v); 29 | visit[v] = true; 30 | } 31 | } 32 | } 33 | } 34 | 35 | // TC:O(n ^ 2) SC:O(n) 36 | public static int countCircles1(int[][] in) { 37 | int count = 0; 38 | boolean[] visit = new boolean[in.length]; 39 | for (int u = 0; u < in.length; ++u) { 40 | if (visit[u] == false) { 41 | dfs(u, in, visit); 42 | ++count; 43 | } 44 | } 45 | return count; 46 | } 47 | 48 | // TC:O(n ^ 2) SC:O(n) 49 | public static int countCircles2(int[][] in) { 50 | int count = 0; 51 | boolean[] visit = new boolean[in.length]; 52 | for (int u = 0; u < in.length; ++u) { 53 | if (visit[u] == false) { 54 | bfs(u, in, visit); 55 | ++count; 56 | } 57 | } 58 | return count; 59 | } 60 | 61 | // TC:O(n ^ 2) SC:O(n) 62 | public static int countCircles3(int[][] in) { 63 | IDisjointSet dset = new WeightedUnionDS(in.length); 64 | for (int i = 1; i < in.length; ++i) { 65 | for (int j = 0; j < i; ++j) { 66 | if (in[i][j] == 1) 67 | dset.union(i, j); 68 | } 69 | } 70 | return dset.size(); 71 | } 72 | 73 | public static void main(String[] args) { 74 | int n = Integer.parseInt(args[0]); 75 | int[][] in = GraphUtils.undirectedRandomGraph(n); 76 | //GraphUtils.display(in); 77 | System.out.println(countCircles1(in)); 78 | System.out.println(countCircles2(in)); 79 | System.out.println(countCircles3(in)); 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /2018-aug/3.graph-problems/src/com/alg/advtop20/graphs/traversal/courseschedule/CourseSchedule.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal.courseschedule; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | import java.util.Stack; 6 | 7 | import com.alg.advtop20.graphs.GraphUtils; 8 | 9 | public class CourseSchedule { 10 | 11 | //TC:O(V ^ 2) SC:O(V) 12 | public static Queue courseSchedule1(int[][] in) { 13 | int[] indegree = new int[in.length]; 14 | Queue q = new LinkedList(); 15 | for(int i = 0; i < in.length; ++i) { 16 | for(int j = 0; j < in.length; ++j) { 17 | if(in[i][j] == 1) 18 | ++indegree[j]; 19 | } 20 | } 21 | for(int k = 1; k <= in.length; ++k) { 22 | int i; 23 | for(i = 0; i < in.length; ++i) { 24 | if(indegree[i] == 0) { 25 | indegree[i] = -1; 26 | q.add(i); 27 | for(int j = 0; j < in.length; ++j) { 28 | if(in[i][j] == 1) 29 | --indegree[j]; 30 | } 31 | break; 32 | } 33 | } 34 | if(i == in.length) return null; 35 | } 36 | return q; 37 | } 38 | 39 | private static boolean dfs(int u, int[][] in, int[] visit, Stack st) { 40 | visit[u] = 1; 41 | for(int v = 0; v < in.length; ++v) { 42 | if(in[u][v] == 1) { 43 | //forward edge 44 | if(visit[v] == 0) { 45 | if(dfs(v, in, visit, st)) return true; 46 | } else { //cyclic edge 47 | if(visit[v] == 1) return true; 48 | } 49 | } 50 | } 51 | visit[u] = 2; 52 | st.push(u); 53 | return false; 54 | } 55 | //TC:O(V ^ 2) SC:O(V) 56 | public static Stack courseSchedule2(int[][] in) { 57 | int[] visit = new int[in.length]; 58 | Stack st = new Stack(); 59 | for(int u = 0; u < in.length; ++u) { 60 | if(visit[u] == 0) 61 | if(dfs(u, in, visit, st)) return null; 62 | } 63 | return st; 64 | } 65 | public static void main(String[] args) { 66 | int n = Integer.parseInt(args[0]); 67 | int[][] in = GraphUtils.completeDirectedGraph(n); 68 | GraphUtils.printGraph(in); 69 | System.out.println(courseSchedule1(in)); 70 | System.out.println(courseSchedule2(in)); 71 | 72 | System.out.println(); 73 | in = GraphUtils.randomDirectedGraph(n); 74 | GraphUtils.printGraph(in); 75 | System.out.println(courseSchedule1(in)); 76 | System.out.println(courseSchedule2(in)); 77 | 78 | 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/MinCutPalPartitioning1.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.advdp; 2 | 3 | public class MinCutPalPartitioning1 { 4 | 5 | private static boolean isPalindrome(String s, int i, int j) { 6 | while (i < j) { 7 | if (s.charAt(i) != s.charAt(j)) 8 | return false; 9 | ++i; 10 | --j; 11 | } 12 | return true; 13 | } 14 | 15 | public static int minCuts1(String s) { 16 | return auxCuts1(0, s.length()-1, s); 17 | } 18 | 19 | private static int auxCuts1(int i, int j, String s) { 20 | if (i >= j || isPalindrome(s, i, j)) 21 | return 0; 22 | int minCuts = Integer.MAX_VALUE; 23 | for (int k = i; k < j; ++k) { 24 | int leftCuts = auxCuts1(i, k, s); 25 | int rightCuts = auxCuts1(k + 1, j, s); 26 | minCuts = Math.min(minCuts, leftCuts + rightCuts + 1); 27 | } 28 | return minCuts; 29 | } 30 | 31 | public static int minCuts21(String s) { 32 | int[][] mem = new int[s.length()][s.length()]; 33 | auxCuts21(0, s.length()-1, s, mem); 34 | return mem[0][s.length()-1]; 35 | } 36 | 37 | private static int auxCuts21(int i, int j, String s, int[][] mem) { 38 | if (i >= j || isPalindrome(s, i, j)) 39 | return 0; 40 | if (mem[i][j] != 0) 41 | return mem[i][j]; 42 | int minCuts = Integer.MAX_VALUE; 43 | for (int k = i; k < j; ++k) { 44 | int leftCuts = auxCuts21(i, k, s, mem); 45 | int rightCuts = auxCuts21(k + 1, j, s, mem); 46 | minCuts = Math.min(minCuts, leftCuts + rightCuts + 1); 47 | } 48 | mem[i][j] = minCuts; 49 | return minCuts; 50 | } 51 | 52 | public static int minCuts22(String s) { 53 | int n = s.length(); 54 | int[][] mem = new int[n][n]; 55 | for (int i = 0; i < n; ++i) 56 | mem[i][i] = 0; 57 | for (int i = n - 1; i >= 0; --i) { 58 | for (int j = i + 1; j < n; ++j) { 59 | if (isPalindrome(s, i, j)) 60 | mem[i][j] = 0; 61 | else { 62 | int mcuts = Integer.MAX_VALUE; 63 | for (int k = i; k < j; ++k) { 64 | int leftCuts = mem[i][k]; 65 | int rightCuts = mem[k + 1][j]; 66 | mcuts = Math.min(mcuts, leftCuts + rightCuts + 1); 67 | } 68 | mem[i][j] = mcuts; 69 | } 70 | } 71 | } 72 | return mem[0][n-1]; 73 | } 74 | 75 | public static void main(String[] args) { 76 | //System.out.println(minCuts1(args[0])); 77 | System.out.println(minCuts21(args[0])); 78 | System.out.println(minCuts22(args[0])); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/dp1/MinCutPalPartitioning1.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp1; 2 | 3 | public class MinCutPalPartitioning1 { 4 | 5 | private static boolean isPalindrome(String s, int i, int j) { 6 | while (i < j) { 7 | if (s.charAt(i) != s.charAt(j)) 8 | return false; 9 | ++i; 10 | --j; 11 | } 12 | return true; 13 | } 14 | 15 | public static int minCuts1(String s) { 16 | return auxCuts1(0, s.length()-1, s); 17 | } 18 | 19 | private static int auxCuts1(int i, int j, String s) { 20 | if (i >= j || isPalindrome(s, i, j)) 21 | return 0; 22 | int minCuts = Integer.MAX_VALUE; 23 | for (int k = i; k < j; ++k) { 24 | int leftCuts = auxCuts1(i, k, s); 25 | int rightCuts = auxCuts1(k + 1, j, s); 26 | minCuts = Math.min(minCuts, leftCuts + rightCuts + 1); 27 | } 28 | return minCuts; 29 | } 30 | 31 | public static int minCuts21(String s) { 32 | int[][] mem = new int[s.length()][s.length()]; 33 | auxCuts21(0, s.length()-1, s, mem); 34 | return mem[0][s.length()-1]; 35 | } 36 | 37 | private static int auxCuts21(int i, int j, String s, int[][] mem) { 38 | if (i >= j || isPalindrome(s, i, j)) 39 | return 0; 40 | if (mem[i][j] != 0) 41 | return mem[i][j]; 42 | int minCuts = Integer.MAX_VALUE; 43 | for (int k = i; k < j; ++k) { 44 | int leftCuts = auxCuts21(i, k, s, mem); 45 | int rightCuts = auxCuts21(k + 1, j, s, mem); 46 | minCuts = Math.min(minCuts, leftCuts + rightCuts + 1); 47 | } 48 | mem[i][j] = minCuts; 49 | return minCuts; 50 | } 51 | 52 | public static int minCuts22(String s) { 53 | int n = s.length(); 54 | int[][] mem = new int[n][n]; 55 | for (int i = 0; i < n; ++i) 56 | mem[i][i] = 0; 57 | for (int i = n - 1; i >= 0; --i) { 58 | for (int j = i + 1; j < n; ++j) { 59 | if (isPalindrome(s, i, j)) 60 | mem[i][j] = 0; 61 | else { 62 | int mcuts = Integer.MAX_VALUE; 63 | for (int k = i; k < j; ++k) { 64 | int leftCuts = mem[i][k]; 65 | int rightCuts = mem[k + 1][j]; 66 | mcuts = Math.min(mcuts, leftCuts + rightCuts + 1); 67 | } 68 | mem[i][j] = mcuts; 69 | } 70 | } 71 | } 72 | return mem[0][n-1]; 73 | } 74 | 75 | public static void main(String[] args) { 76 | //System.out.println(minCuts1(args[0])); 77 | System.out.println(minCuts21(args[0])); 78 | System.out.println(minCuts22(args[0])); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /2017-may/2.dynamic programming/src/com/alg/top20/adv/dp/LISLength.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.adv.dp; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.Random; 6 | 7 | public class LISLength { 8 | 9 | public static int LIS1(int[] in) { 10 | int max = 0; 11 | for(int i = in.length; i >= 1; --i) 12 | max = Math.max(max, auxLIS1(i, in)); 13 | return max; 14 | } 15 | private static int auxLIS1(int i, int[] in) { 16 | int res = 0; 17 | for(int j = 1; j < i; ++j) { 18 | if(in[i-1] > in[j-1]) 19 | res = Math.max(res, auxLIS1(j, in)); 20 | } 21 | return res+1; 22 | } 23 | //TC:O(n ^ 2) SC:O(n) ~ n + n 24 | public static int LIS2(int[] in) { 25 | int[] mem = new int[in.length+1]; 26 | int max = 0; 27 | for(int i = in.length; i >= 1; --i) 28 | max = Math.max(max, mem[i]!=0?mem[i]:auxLIS2(i, in, mem)); 29 | return max; 30 | } 31 | private static int auxLIS2(int i, int[] in, int[] mem) { 32 | int res = 0; 33 | for(int j = 1; j < i; ++j) { 34 | if(in[i-1] > in[j-1]) 35 | res = Math.max(res, mem[j] != 0? mem[j]: auxLIS2(j, in, mem)); 36 | } 37 | return mem[i] = res+1; 38 | } 39 | 40 | //TC:O(n ^ 2) SC:O(n) 41 | public static int LIS3(int[] in) { 42 | int[] mem = new int[in.length+1]; 43 | int max = 0; 44 | mem[0] = 0; 45 | for(int i = 1; i <= in.length; ++i) { 46 | int res = 0; 47 | for(int j = 1; j < i; ++j) { 48 | if(in[i-1] > in[j-1]) 49 | res = Math.max(res, mem[j]); 50 | } 51 | mem[i] = res+1; 52 | max = Math.max(max, mem[i]); 53 | } 54 | return max; 55 | } 56 | 57 | //TC:O(n log n) SC:O(n) 58 | public static int LIS4(int[] in) { 59 | ArrayList mem = new ArrayList(); 60 | for(int i = 0; i < in.length; ++i) { 61 | int pos = Collections.binarySearch(mem, in[i]); 62 | if(pos >= 0) continue; 63 | pos *= -1; 64 | if(pos > mem.size()) 65 | mem.add(in[i]); 66 | else 67 | mem.set(pos-1, in[i]); 68 | } 69 | return mem.size(); 70 | } 71 | 72 | 73 | public static void main(String[] args) { 74 | int n = Integer.parseInt(args[0]); 75 | int[] in = new int[n]; 76 | Random r = new Random(); 77 | for(int i = 0; i < n; ++i) 78 | in[i] = r.nextInt(2*n) + 6; 79 | //System.out.println(Arrays.toString(in)); 80 | //System.out.println(Arrays.toString(in)); 81 | //System.out.println(LIS1(in)); 82 | System.out.println(LIS3(in)); 83 | System.out.println(LIS4(in)); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /2017-may/3.backtracking/src/com/alg/top20/bt/SudokuSolver.java: -------------------------------------------------------------------------------- 1 | package com.alg.top20.bt; 2 | 3 | import java.util.Arrays; 4 | 5 | public class SudokuSolver { 6 | 7 | // recursion: 8 | public static void sudokuSolver1(int[][] in) { 9 | auxSolver1(0, 0, in); 10 | } 11 | 12 | private static void display(int[][] in) { 13 | for (int i = 0; i < 9; ++i) { 14 | System.out.println(Arrays.toString(in[i])); 15 | } 16 | System.out.println(); 17 | } 18 | 19 | private static boolean isValid1(int[][] in) { 20 | //validate the 81 cell grid 21 | return true; 22 | } 23 | 24 | private static void auxSolver1(int r, int c, int[][] in) { 25 | if (r == 9) { 26 | if (isValid1(in)) 27 | display(in); 28 | return; 29 | } 30 | if (in[r][c] != 0) { 31 | auxSolver1(c == 8 ? r + 1 : r, (c + 1) % 9, in); 32 | } else { 33 | for (int d = 1; d <= 9; ++d) { 34 | in[r][c] = d; 35 | auxSolver1(c == 8 ? r + 1 : r, (c + 1) % 9, in); 36 | } 37 | in[r][c] = 0; 38 | } 39 | } 40 | 41 | // backtracking: 42 | public static void sudokuSolver2(int[][] in) { 43 | auxSolver2(0, 0, in); 44 | } 45 | 46 | private static boolean isValid2(int r, int c, int d, int[][] in) { 47 | //row & column check 48 | for(int j = 0; j < 9; ++j) { 49 | if(in[r][j] == d) return false; 50 | if(in[j][c] == d) return false; 51 | } 52 | //box check 53 | int startr = r / 3 * 3; 54 | int startc = c / 3 * 3; 55 | for(int i = 0; i < 3; ++i) { 56 | for(int j = 0; j < 3; ++j) { 57 | if(in[startr+i][startc+j] == d) return false; 58 | } 59 | } 60 | return true; 61 | } 62 | 63 | private static void auxSolver2(int r, int c, int[][] in) { 64 | if (r == 9) { 65 | display(in); 66 | return; 67 | } 68 | if (in[r][c] != 0) { 69 | auxSolver2(c == 8 ? r + 1 : r, (c + 1) % 9, in); 70 | } else { 71 | for (int d = 1; d <= 9; ++d) { 72 | if (isValid2(r,c,d,in)) { 73 | in[r][c] = d; 74 | auxSolver2(c == 8 ? r + 1 : r, (c + 1) % 9, in); 75 | } 76 | } 77 | in[r][c] = 0; 78 | } 79 | } 80 | 81 | //todo: automate test case 82 | public static void main(String[] args) { 83 | int[][] in = 84 | { {1,0,0,0,5,0,0,0,9}, 85 | {0,0,0,4,0,9,0,0,0}, 86 | {0,0,0,3,8,6,0,0,0}, 87 | {5,9,0,0,0,0,0,6,8}, 88 | {4,0,0,8,9,2,0,0,7}, 89 | {0,0,0,0,0,0,0,0,0}, 90 | {0,0,1,7,0,5,8,0,0}, 91 | {0,3,0,0,0,0,0,1,0}, 92 | {9,8,5,0,4,0,7,3,2} 93 | }; 94 | display(in); 95 | System.out.println(); 96 | sudokuSolver2(in); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /2018-aug/3.graph-problems/src/com/alg/advtop20/graphs/st/MinimumRentalConnections.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.st; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.Comparator; 7 | import java.util.List; 8 | 9 | class DisjointSet { 10 | private int[] parent; 11 | private int[] rank; 12 | int nsets; 13 | 14 | public DisjointSet(int n) { 15 | parent = new int[n]; 16 | rank = new int[n]; 17 | for(int i = 0; i < n; ++i) { 18 | parent[i] = i; 19 | rank[i] = 1; 20 | } 21 | nsets = n; 22 | } 23 | 24 | public int find(int x) { 25 | if(parent[x] == x) return x; 26 | return parent[x] = find(parent[x]); 27 | } 28 | 29 | public void union(int x, int y) { 30 | int rx = find(x); 31 | int ry = find(y); 32 | if(rx != ry) { 33 | --nsets; 34 | if(rank[rx] > rank[ry]) 35 | parent[ry] = rx; 36 | else if(rank[ry] > rank[rx]) 37 | parent[rx] = ry; 38 | else { 39 | parent[ry] = rx; 40 | ++rank[rx]; 41 | } 42 | } 43 | } 44 | 45 | public int getNumSets() { 46 | return nsets; 47 | } 48 | 49 | public void display() { 50 | System.out.println(Arrays.toString(parent)); 51 | System.out.println(Arrays.toString(rank)); 52 | } 53 | 54 | } 55 | class Edge { 56 | int start; 57 | int end; 58 | int weight; 59 | public Edge(int start, int end, int weight) { 60 | super(); 61 | this.start = start; 62 | this.end = end; 63 | this.weight = weight; 64 | } 65 | 66 | } 67 | 68 | class WeightComparator implements Comparator { 69 | 70 | @Override 71 | public int compare(Edge e1, Edge e2) { 72 | return e1.weight - e2.weight; 73 | } 74 | 75 | } 76 | public class MinimumRentalConnections { 77 | 78 | public static int findMinRentalCost(int[][] in) { 79 | List edges = new ArrayList(); 80 | //E 81 | for(int i = 0; i < in.length; ++i) { 82 | for(int j = i+1; j < in.length; ++j) { 83 | if(in[i][j] != 0) 84 | edges.add(new Edge(i, j, in[i][j])); 85 | } 86 | } 87 | //E log E(merge/quick) or E(for radix sort) 88 | Collections.sort(edges, new WeightComparator()); 89 | DisjointSet dset = new DisjointSet(in.length); 90 | int totcost = 0, count = 0; 91 | //E 92 | for(Edge e: edges) { 93 | if(dset.find(e.start) != dset.find(e.end)){ 94 | dset.union(e.start, e.end); 95 | totcost += e.weight; 96 | ++count; 97 | if(count == in.length-1) break; 98 | } 99 | } 100 | return totcost; 101 | } 102 | public static void main(String[] args) { 103 | // TODO Auto-generated method stub 104 | 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/st/MinimumRentalConnections.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.st; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.Comparator; 7 | import java.util.List; 8 | 9 | class DisjointSet { 10 | private int[] parent; 11 | private int[] rank; 12 | int nsets; 13 | 14 | public DisjointSet(int n) { 15 | parent = new int[n]; 16 | rank = new int[n]; 17 | for(int i = 0; i < n; ++i) { 18 | parent[i] = i; 19 | rank[i] = 1; 20 | } 21 | nsets = n; 22 | } 23 | 24 | public int find(int x) { 25 | if(parent[x] == x) return x; 26 | return parent[x] = find(parent[x]); 27 | } 28 | 29 | public void union(int x, int y) { 30 | int rx = find(x); 31 | int ry = find(y); 32 | if(rx != ry) { 33 | --nsets; 34 | if(rank[rx] > rank[ry]) 35 | parent[ry] = rx; 36 | else if(rank[ry] > rank[rx]) 37 | parent[rx] = ry; 38 | else { 39 | parent[ry] = rx; 40 | ++rank[rx]; 41 | } 42 | } 43 | } 44 | 45 | public int getNumSets() { 46 | return nsets; 47 | } 48 | 49 | public void display() { 50 | System.out.println(Arrays.toString(parent)); 51 | System.out.println(Arrays.toString(rank)); 52 | } 53 | 54 | } 55 | class Edge { 56 | int start; 57 | int end; 58 | int weight; 59 | public Edge(int start, int end, int weight) { 60 | super(); 61 | this.start = start; 62 | this.end = end; 63 | this.weight = weight; 64 | } 65 | 66 | } 67 | 68 | class WeightComparator implements Comparator { 69 | 70 | @Override 71 | public int compare(Edge e1, Edge e2) { 72 | return e1.weight - e2.weight; 73 | } 74 | 75 | } 76 | public class MinimumRentalConnections { 77 | 78 | public static int findMinRentalCost(int[][] in) { 79 | List edges = new ArrayList(); 80 | //E 81 | for(int i = 0; i < in.length; ++i) { 82 | for(int j = i+1; j < in.length; ++j) { 83 | if(in[i][j] != 0) 84 | edges.add(new Edge(i, j, in[i][j])); 85 | } 86 | } 87 | //E log E(merge/quick) or E(for radix sort) 88 | Collections.sort(edges, new WeightComparator()); 89 | DisjointSet dset = new DisjointSet(in.length); 90 | int totcost = 0, count = 0; 91 | //E 92 | for(Edge e: edges) { 93 | if(dset.find(e.start) != dset.find(e.end)){ 94 | dset.union(e.start, e.end); 95 | totcost += e.weight; 96 | ++count; 97 | if(count == in.length-1) break; 98 | } 99 | } 100 | return totcost; 101 | } 102 | public static void main(String[] args) { 103 | // TODO Auto-generated method stub 104 | 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/GraphCycle.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | 6 | import com.alg.advtop20.graph.disjointset.IDisjointSet; 7 | import com.alg.advtop20.graph.disjointset.WeightedUnionDS; 8 | 9 | public class GraphCycle { 10 | // TC:O(n ^ 2) SC:O(n) 11 | public static boolean hasCycle1(int[][] in) { 12 | boolean[] visit = new boolean[in.length]; 13 | for (int u = 0; u < in.length; ++u) { 14 | if (visit[u] == false) { 15 | if (dfs(u, u, in, visit)) 16 | return true; 17 | } 18 | } 19 | return false; 20 | } 21 | 22 | private static boolean dfs(int u, int parent, int[][] in, boolean[] visit) { 23 | visit[u] = true; 24 | for (int v = 0; v < in.length; ++v) { 25 | if (in[u][v] == 1) { 26 | if (visit[v] == false) { // action to be taken if v is not visited 27 | if (dfs(v, u, in, visit)) 28 | return true; 29 | } else { // action to be taken if v is already visited 30 | if (v != parent) 31 | return true; 32 | } 33 | } 34 | } 35 | return false; 36 | } 37 | 38 | // TC:O(n ^ 2) SC:O(n) 39 | public static boolean hasCycle2(int[][] in) { 40 | int[] visit = new int[in.length]; 41 | for (int u = 0; u < in.length; ++u) { 42 | if (visit[u] == 0) { 43 | if (bfs(u, in, visit)) 44 | return true; 45 | } 46 | } 47 | return false; 48 | } 49 | 50 | private static boolean bfs(int u, int[][] in, int[] visit) { 51 | Queue q = new LinkedList(); 52 | q.add(u); 53 | visit[u] = 1; 54 | while (!q.isEmpty()) { 55 | u = q.remove(); 56 | visit[u] = 2; 57 | for (int v = 0; v < in.length; ++v) { 58 | if (in[u][v] == 1) { 59 | if (visit[v] == 0) { // node not yet visited 60 | q.add(v); 61 | visit[v] = 1; 62 | } else { // node already visited 63 | if (visit[v] == 1) 64 | return true; 65 | } 66 | } 67 | } 68 | } 69 | return false; 70 | } 71 | 72 | // TC:O(n ^ 2) SC:O(n) 73 | public static boolean hasCycle3(int[][] in) { 74 | IDisjointSet dset = new WeightedUnionDS(in.length); 75 | for (int i = 1; i < in.length; ++i) { 76 | for (int j = 0; j < i; ++j) { 77 | if (in[i][j] == 1) { 78 | if (dset.find(i) == dset.find(j)) 79 | return true; 80 | dset.union(i, j); 81 | } 82 | } 83 | } 84 | return false; 85 | } 86 | 87 | public static void main(String[] args) { 88 | int n = Integer.parseInt(args[0]); 89 | int[][] in = GraphUtils.undirectedRandomGraph(n); 90 | GraphUtils.display(in); 91 | System.out.println(hasCycle1(in)); 92 | System.out.println(hasCycle2(in)); 93 | System.out.println(hasCycle3(in)); 94 | 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /2018-aug/3.graph-problems/src/com/alg/advtop20/graphs/GraphUtils.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | public class GraphUtils { 7 | 8 | public static void printGraph(int[][] in) { 9 | for(int[] tmp:in) { 10 | System.out.println(Arrays.toString(tmp)); 11 | } 12 | } 13 | 14 | public static int[][] randomGraph(int n) { 15 | int[][] in = new int[n][n]; 16 | Random r = new Random(100); 17 | for(int k = 1; k <= n; ++k) { 18 | int ri = r.nextInt(n); 19 | int rj = r.nextInt(n); 20 | if(ri == rj) continue; 21 | in[ri][rj] = 1; 22 | in[rj][ri] = 1; 23 | } 24 | return in; 25 | } 26 | 27 | public static int[][] completeGraph(int n) { 28 | int[][] in = new int[n][n]; 29 | for(int i = 0; i < n; ++i) { 30 | for(int j = i+1; j < n; ++j) { 31 | in[i][j] = 1; 32 | in[j][i] = 1; 33 | } 34 | } 35 | return in; 36 | } 37 | 38 | public static int[][] convertToGraph(int n, int[][] input) { 39 | int[][] in = new int[n][n]; 40 | for(int[] tmp:input) { 41 | in[tmp[0]][tmp[1]] = 1; 42 | in[tmp[1]][tmp[0]] = 1; 43 | } 44 | return in; 45 | } 46 | 47 | public static int[][] randomDirectedGraph(int n) { 48 | int[][] in = new int[n][n]; 49 | Random r = new Random(100); 50 | for(int k = 1; k <= n; ++k) { 51 | int ri = r.nextInt(n); 52 | int rj = r.nextInt(n); 53 | if(ri == rj) continue; 54 | in[ri][rj] = 1; 55 | } 56 | return in; 57 | } 58 | public static int[][] completeDirectedGraph(int n) { 59 | int[][] in = new int[n][n]; 60 | for(int i = 0; i < n; ++i) { 61 | for(int j = i+1; j < n; ++j) { 62 | in[i][j] = 1; 63 | } 64 | } 65 | return in; 66 | } 67 | 68 | public static int[][] completeWeightedGraph(int n) { 69 | int[][] in = new int[n][n]; 70 | Random r = new Random(100); 71 | for(int i = 0; i < n; ++i) { 72 | for(int j = i+1; j < n; ++j) { 73 | int tmp = r.nextInt(10)+1; 74 | in[i][j] = tmp; 75 | in[j][i] = tmp; 76 | } 77 | } 78 | return in; 79 | } 80 | 81 | public static int[][] completeDirectedWeightedGraph(int n) { 82 | int[][] in = new int[n][n]; 83 | Random r = new Random(100); 84 | for(int i = 0; i < n; ++i) { 85 | for(int j = i+1; j < n; ++j) { 86 | int tmp = r.nextInt(10)+1; 87 | in[i][j] = tmp; 88 | } 89 | } 90 | return in; 91 | } 92 | 93 | public static int[][] randomDirectedWeightedGraph(int n) { 94 | int[][] in = new int[n][n]; 95 | Random r = new Random(100); 96 | for(int k = 1; k <= n; ++k) { 97 | int ri = r.nextInt(n); 98 | int rj = r.nextInt(n); 99 | if(ri == rj) continue; 100 | in[ri][rj] = r.nextInt(10)+1; 101 | } 102 | return in; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/segmentree/LinkedSegmentTree.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.segmentree; 2 | 3 | import java.util.Arrays; 4 | 5 | class SegmentNode { 6 | int start; 7 | int end; 8 | int sum; 9 | SegmentNode left; 10 | SegmentNode right; 11 | 12 | public SegmentNode(int start, int end) { 13 | this.start = start; 14 | this.end = end; 15 | } 16 | 17 | public SegmentNode(int start, int end, int sum) { 18 | this(start, end); 19 | this.sum = sum; 20 | } 21 | 22 | public boolean intersect(int i, int j) { 23 | if (j < start || i > end) 24 | return false; 25 | return true; 26 | } 27 | } 28 | 29 | public class LinkedSegmentTree implements ISegmentTree { 30 | private SegmentNode root; 31 | private int[] in; 32 | 33 | // O(n) 34 | public LinkedSegmentTree(int[] in) { 35 | this.in = in; 36 | root = build(in, 0, in.length - 1); 37 | } 38 | 39 | private int get(SegmentNode left) { 40 | return left == null ? 0 : left.sum; 41 | } 42 | 43 | private SegmentNode build(int[] in, int l, int r) { 44 | if (l > r) 45 | return null; 46 | if (l == r) 47 | return new SegmentNode(l, r, in[l]); 48 | SegmentNode tmp = new SegmentNode(l, r); 49 | int m = l + (r - l) / 2; 50 | tmp.left = build(in, l, m); 51 | tmp.right = build(in, m + 1, r); 52 | tmp.sum = get(tmp.left) + get(tmp.right); 53 | return tmp; 54 | } 55 | 56 | // O(log n) 57 | public void update(int i, int x) { 58 | in[i] = x; 59 | auxUpdate(root, i, x); 60 | } 61 | 62 | private void auxUpdate(SegmentNode root, int i, int x) { 63 | if (i == root.start && i == root.end) { 64 | root.sum = x; 65 | return; 66 | } 67 | int m = (root.start + root.end) / 2; 68 | if (i <= m) 69 | auxUpdate(root.left, i, x); 70 | else 71 | auxUpdate(root.right, i, x); 72 | root.sum = get(root.left) + get(root.right); 73 | } 74 | 75 | // O(log n) 76 | public int rangeSum(int i, int j) { 77 | return auxRangeSum(root, i, j); 78 | } 79 | 80 | private int auxRangeSum(SegmentNode root, int i, int j) { 81 | if (i > j || !root.intersect(i, j)) 82 | return 0; 83 | if (root.left == null && root.right == null) 84 | return root.sum; 85 | return auxRangeSum(root.left, i, j) + auxRangeSum(root.right, i, j); 86 | } 87 | 88 | public void display() { 89 | System.out.println(Arrays.toString(in)); 90 | auxDisplay(root, 0, "Root"); 91 | } 92 | 93 | private void auxDisplay(SegmentNode root, int nspaces, String type) { 94 | if (root == null) 95 | return; 96 | for (int i = 0; i < nspaces; ++i) 97 | System.out.print(' '); 98 | System.out.println("(" + root.start + "," + root.end + "," + root.sum + "," + type + ")"); 99 | auxDisplay(root.left, nspaces + 4, "L"); 100 | auxDisplay(root.right, nspaces + 4, "R"); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /2019-december/2.graph problems/AllPairsShortestPath.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graph; 2 | 3 | public class AllPairsShortestPath { 4 | 5 | public static void allPairsShortestPath1(int[][] in) { 6 | for (int i = 0; i < in.length; ++i) { 7 | for (int j = 0; j < in.length; ++j) { 8 | System.out.println(shortestPath1(i, j, 0, in)); 9 | } 10 | } 11 | } 12 | 13 | private static int getSum(int left, int right) { 14 | if (left == Integer.MAX_VALUE || right == Integer.MAX_VALUE) 15 | return Integer.MAX_VALUE; 16 | return left + right; 17 | } 18 | 19 | private static int shortestPath1(int i, int j, int k, int[][] in) { 20 | if (i == j || k == in.length) 21 | return in[i][j]; 22 | int exclusive = shortestPath1(i, j, k + 1, in); 23 | int inclusive_left = shortestPath1(i, k, k + 1, in); 24 | int inclusive_right = shortestPath1(k, j, k + 1, in); 25 | return Math.min(exclusive, getSum(inclusive_left, inclusive_right)); 26 | } 27 | 28 | public static void allPairsShortestPath2(int[][] in) { 29 | int[][][] mem = new int[in.length][in.length][in.length]; 30 | for (int i = 0; i < in.length; ++i) { 31 | for (int j = 0; j < in.length; ++j) { 32 | System.out.println(shortestPath2(i, j, 0, in, mem)); 33 | } 34 | } 35 | } 36 | 37 | private static int shortestPath2(int i, int j, int k, int[][] in, int[][][] mem) { 38 | if (i == j || k == in.length) 39 | return in[i][j]; 40 | if (mem[i][j][k] != 0) 41 | return mem[i][j][k]; 42 | int exclusive = shortestPath2(i, j, k + 1, in, mem); 43 | int inclusive_left = shortestPath2(i, k, k + 1, in, mem); 44 | int inclusive_right = shortestPath2(k, j, k + 1, in, mem); 45 | return mem[i][j][k] = Math.min(exclusive, getSum(inclusive_left, inclusive_right)); 46 | } 47 | 48 | public static void allPairsShortestPath3(int[][] in) { 49 | int[][][] mem = new int[in.length][in.length][in.length + 1]; 50 | for (int i = 0; i < in.length; ++i) { 51 | for (int j = 0; j < in.length; ++j) { 52 | mem[i][j][in.length] = in[i][j]; 53 | } 54 | } 55 | for (int k = in.length - 1; k >= 0; --k) { 56 | for (int i = 0; i < in.length; ++i) { 57 | for (int j = 0; j < in.length; ++j) { 58 | int exclusive = mem[i][j][k + 1]; 59 | int inclusive_left = mem[i][k][k + 1]; 60 | int inclusive_right = mem[k][j][k + 1]; 61 | mem[i][j][k] = Math.min(exclusive, getSum(inclusive_left, inclusive_right)); 62 | } 63 | } 64 | } 65 | for (int i = 0; i < in.length; ++i) { 66 | for (int j = 0; j < in.length; ++j) 67 | System.out.println(mem[i][j][0]); 68 | } 69 | 70 | } 71 | 72 | public static void main(String[] args) { 73 | int n = Integer.parseInt(args[0]); 74 | int[][] in = GraphUtils.directedWeightedRandomGraph(n); 75 | GraphUtils.display(in); 76 | allPairsShortestPath1(in); 77 | System.out.println(); 78 | allPairsShortestPath2(in); 79 | System.out.println(); 80 | allPairsShortestPath3(in); 81 | } 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/traversal/CountFriendCircles.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | import java.util.Arrays; 4 | import java.util.LinkedList; 5 | import java.util.Queue; 6 | 7 | class DisjointSet { 8 | private int[] parent; 9 | private int[] rank; 10 | int nsets; 11 | 12 | public DisjointSet(int n) { 13 | parent = new int[n]; 14 | rank = new int[n]; 15 | for(int i = 0; i < n; ++i) { 16 | parent[i] = i; 17 | rank[i] = 1; 18 | } 19 | nsets = n; 20 | } 21 | 22 | public int find(int x) { 23 | if(parent[x] == x) return x; 24 | return parent[x] = find(parent[x]); 25 | } 26 | 27 | public void union(int x, int y) { 28 | int rx = find(x); 29 | int ry = find(y); 30 | if(rx != ry) { 31 | --nsets; 32 | if(rank[rx] > rank[ry]) 33 | parent[ry] = rx; 34 | else if(rank[ry] > rank[rx]) 35 | parent[rx] = ry; 36 | else { 37 | parent[ry] = rx; 38 | ++rank[rx]; 39 | } 40 | } 41 | } 42 | 43 | public int getNumSets() { 44 | return nsets; 45 | } 46 | 47 | public void display() { 48 | System.out.println(Arrays.toString(parent)); 49 | System.out.println(Arrays.toString(rank)); 50 | } 51 | 52 | } 53 | public class CountFriendCircles { 54 | 55 | //TC:O(V ^ 2) SC:O(V) 56 | public static int countCircles1(int[][] in) { 57 | DisjointSet dset = new DisjointSet(in.length); 58 | for(int i = 1; i < in.length; ++i) { 59 | for(int j = 0; j < i; ++j) { 60 | if(in[i][j] == 1) 61 | dset.union(i, j); 62 | } 63 | } 64 | return dset.getNumSets(); 65 | } 66 | 67 | private static void dfs(int u, int[][] in, boolean[] visit) { 68 | visit[u] = true; 69 | for(int v = 0; v < in.length; ++v) { 70 | if(in[u][v] == 1 && visit[v] == false) 71 | dfs(v, in, visit); 72 | } 73 | } 74 | private static void bfs(int u, int[][] in, boolean[] visit) { 75 | Queue q = new LinkedList(); 76 | q.add(u); 77 | visit[u] = true; 78 | while(! q.isEmpty()) { 79 | u = q.remove(); 80 | for(int v = 0; v < in.length; ++v) { 81 | if(in[u][v] == 1 && visit[v] == false) { 82 | q.add(v); 83 | visit[v] = true; 84 | } 85 | } 86 | } 87 | } 88 | //TC:O(V ^ 2) SC:O(V) 89 | public static int countCircles2(int[][] in) { 90 | int count = 0; 91 | boolean[] visit = new boolean[in.length]; 92 | for(int u = 0; u < in.length; ++u) { 93 | if(visit[u] == false) { 94 | dfs(u, in, visit); 95 | //bfs(u, in, visit); 96 | ++count; 97 | } 98 | } 99 | return count; 100 | } 101 | 102 | public static void main(String[] args) { 103 | int n = Integer.parseInt(args[0]); 104 | int[][] in = GraphUtils.randomGraph(n); 105 | GraphUtils.printGraph(in); 106 | System.out.println(countCircles1(in)); 107 | System.out.println(countCircles2(in)); 108 | in = GraphUtils.completeGraph(n); 109 | GraphUtils.printGraph(in); 110 | System.out.println(countCircles1(in)); 111 | System.out.println(countCircles2(in)); 112 | 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/graph-problems/src/com/alg/advtop20/graphs/traversal/CountFriendCircles.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal; 2 | 3 | import java.util.Arrays; 4 | import java.util.LinkedList; 5 | import java.util.Queue; 6 | 7 | class DisjointSet { 8 | private int[] parent; 9 | private int[] rank; 10 | int nsets; 11 | 12 | public DisjointSet(int n) { 13 | parent = new int[n]; 14 | rank = new int[n]; 15 | for(int i = 0; i < n; ++i) { 16 | parent[i] = i; 17 | rank[i] = 1; 18 | } 19 | nsets = n; 20 | } 21 | 22 | public int find(int x) { 23 | if(parent[x] == x) return x; 24 | return parent[x] = find(parent[x]); 25 | } 26 | 27 | public void union(int x, int y) { 28 | int rx = find(x); 29 | int ry = find(y); 30 | if(rx != ry) { 31 | --nsets; 32 | if(rank[rx] > rank[ry]) 33 | parent[ry] = rx; 34 | else if(rank[ry] > rank[rx]) 35 | parent[rx] = ry; 36 | else { 37 | parent[ry] = rx; 38 | ++rank[rx]; 39 | } 40 | } 41 | } 42 | 43 | public int getNumSets() { 44 | return nsets; 45 | } 46 | 47 | public void display() { 48 | System.out.println(Arrays.toString(parent)); 49 | System.out.println(Arrays.toString(rank)); 50 | } 51 | 52 | } 53 | public class CountFriendCircles { 54 | 55 | //TC:O(V ^ 2) SC:O(V) 56 | public static int countCircles1(int[][] in) { 57 | DisjointSet dset = new DisjointSet(in.length); 58 | for(int i = 1; i < in.length; ++i) { 59 | for(int j = 0; j < i; ++j) { 60 | if(in[i][j] == 1) 61 | dset.union(i, j); 62 | } 63 | } 64 | return dset.getNumSets(); 65 | } 66 | 67 | private static void dfs(int u, int[][] in, boolean[] visit) { 68 | visit[u] = true; 69 | for(int v = 0; v < in.length; ++v) { 70 | if(in[u][v] == 1 && visit[v] == false) 71 | dfs(v, in, visit); 72 | } 73 | } 74 | private static void bfs(int u, int[][] in, boolean[] visit) { 75 | Queue q = new LinkedList(); 76 | q.add(u); 77 | visit[u] = true; 78 | while(! q.isEmpty()) { 79 | u = q.remove(); 80 | for(int v = 0; v < in.length; ++v) { 81 | if(in[u][v] == 1 && visit[v] == false) { 82 | q.add(v); 83 | visit[v] = true; 84 | } 85 | } 86 | } 87 | } 88 | //TC:O(V ^ 2) SC:O(V) 89 | public static int countCircles2(int[][] in) { 90 | int count = 0; 91 | boolean[] visit = new boolean[in.length]; 92 | for(int u = 0; u < in.length; ++u) { 93 | if(visit[u] == false) { 94 | dfs(u, in, visit); 95 | //bfs(u, in, visit); 96 | ++count; 97 | } 98 | } 99 | return count; 100 | } 101 | 102 | public static void main(String[] args) { 103 | int n = Integer.parseInt(args[0]); 104 | int[][] in = GraphUtils.randomGraph(n); 105 | GraphUtils.printGraph(in); 106 | System.out.println(countCircles1(in)); 107 | System.out.println(countCircles2(in)); 108 | in = GraphUtils.completeGraph(n); 109 | GraphUtils.printGraph(in); 110 | System.out.println(countCircles1(in)); 111 | System.out.println(countCircles2(in)); 112 | 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /2018-aug/4.file-problems/src/com/alg/advtop20/files/Tail.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.files; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileReader; 6 | import java.io.RandomAccessFile; 7 | import java.util.HashMap; 8 | import java.util.LinkedList; 9 | import java.util.Queue; 10 | 11 | import org.apache.commons.io.input.ReversedLinesFileReader; 12 | 13 | class CircularBuffer { 14 | private Queue buffer; 15 | private int capacity; 16 | 17 | public CircularBuffer(int k) { 18 | capacity = k; 19 | buffer = new LinkedList(); 20 | } 21 | 22 | public void add(String line) { 23 | if(buffer.size() == capacity) { 24 | buffer.remove(); 25 | } 26 | buffer.add(line); 27 | } 28 | 29 | public String getFirst() { 30 | return buffer.peek(); 31 | } 32 | } 33 | public class Tail { 34 | 35 | public static String findNthLinEnd1(String file, int k) throws Exception { 36 | BufferedReader br = new BufferedReader(new FileReader(file)); 37 | String line; 38 | int nlines = 0; 39 | while ((line = br.readLine()) != null) 40 | ++nlines; 41 | br.close(); 42 | if (k > nlines) 43 | return null; 44 | else { 45 | int count = 0; 46 | br = new BufferedReader(new FileReader(file)); 47 | while ((line = br.readLine()) != null) { 48 | if (++count == nlines - k + 1) 49 | return line; 50 | } 51 | } 52 | return null; 53 | } 54 | 55 | public static String findNthLinEnd2(String file, int k) throws Exception { 56 | CircularBuffer cb = new CircularBuffer(k); 57 | BufferedReader br = new BufferedReader(new FileReader(file)); 58 | String line; 59 | while ((line = br.readLine()) != null) 60 | cb.add(line); 61 | br.close(); 62 | return cb.getFirst(); 63 | } 64 | 65 | public static String findNthLinEnd3(String file, int k) throws Exception { 66 | ReversedLinesFileReader rfr = new ReversedLinesFileReader( 67 | new File(file)); 68 | String line = null; 69 | int count = 0; 70 | while ((line = rfr.readLine()) != null) { 71 | if (++count == k) 72 | break; 73 | } 74 | rfr.close(); 75 | return line; 76 | } 77 | 78 | /*public static String findNthLinEnd4(String file, int k) throws Exception { 79 | HashMap line_index = new HashMap(); 80 | RandomAccessFile raf = new RandomAccessFile(file, "r"); 81 | String line; 82 | long count = 1; 83 | line_index.put(count, 0L); 84 | while ((line = raf.readLine()) != null) { 85 | line_index.put(++count, raf.getFilePointer()); 86 | } 87 | System.out.println(line_index); 88 | raf.seek(line_index.get(count - k)); 89 | return raf.readLine(); 90 | } 91 | */ 92 | public static void main(String[] args) throws Exception { 93 | int k = Integer.parseInt(args[1]); 94 | long start = System.currentTimeMillis(); 95 | System.out.println(findNthLinEnd3(args[0], k)); 96 | long end = System.currentTimeMillis(); 97 | System.out.println("Time:" + (end - start) / 1000.0 + " seconds"); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /2018-aug/3.graph-problems/src/com/alg/advtop20/graphs/traversal/friendcircles/CountFriendCircles.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal.friendcircles; 2 | 3 | import java.util.Arrays; 4 | import java.util.LinkedList; 5 | import java.util.Queue; 6 | 7 | import com.alg.advtop20.graphs.GraphUtils; 8 | 9 | class DisjointSet { 10 | private int[] parent; 11 | private int[] rank; 12 | int nsets; 13 | 14 | public DisjointSet(int n) { 15 | parent = new int[n]; 16 | rank = new int[n]; 17 | for(int i = 0; i < n; ++i) { 18 | parent[i] = i; 19 | rank[i] = 1; 20 | } 21 | nsets = n; 22 | } 23 | 24 | public int find(int x) { 25 | if(parent[x] == x) return x; 26 | return parent[x] = find(parent[x]); 27 | } 28 | 29 | public void union(int x, int y) { 30 | int rx = find(x); 31 | int ry = find(y); 32 | if(rx != ry) { 33 | --nsets; 34 | if(rank[rx] > rank[ry]) 35 | parent[ry] = rx; 36 | else if(rank[ry] > rank[rx]) 37 | parent[rx] = ry; 38 | else { 39 | parent[ry] = rx; 40 | ++rank[rx]; 41 | } 42 | } 43 | } 44 | 45 | public int getNumSets() { 46 | return nsets; 47 | } 48 | 49 | public void display() { 50 | System.out.println(Arrays.toString(parent)); 51 | System.out.println(Arrays.toString(rank)); 52 | } 53 | 54 | } 55 | public class CountFriendCircles { 56 | 57 | //TC:O(V ^ 2) SC:O(V) 58 | public static int countCircles1(int[][] in) { 59 | DisjointSet dset = new DisjointSet(in.length); 60 | for(int i = 1; i < in.length; ++i) { 61 | for(int j = 0; j < i; ++j) { 62 | if(in[i][j] == 1) 63 | dset.union(i, j); 64 | } 65 | } 66 | return dset.getNumSets(); 67 | } 68 | 69 | private static void dfs(int u, int[][] in, boolean[] visit) { 70 | visit[u] = true; 71 | for(int v = 0; v < in.length; ++v) { 72 | if(in[u][v] == 1 && visit[v] == false) 73 | dfs(v, in, visit); 74 | } 75 | } 76 | private static void bfs(int u, int[][] in, boolean[] visit) { 77 | Queue q = new LinkedList(); 78 | q.add(u); 79 | visit[u] = true; 80 | while(! q.isEmpty()) { 81 | u = q.remove(); 82 | for(int v = 0; v < in.length; ++v) { 83 | if(in[u][v] == 1 && visit[v] == false) { 84 | q.add(v); 85 | visit[v] = true; 86 | } 87 | } 88 | } 89 | } 90 | //TC:O(V ^ 2) SC:O(V) 91 | public static int countCircles2(int[][] in) { 92 | int count = 0; 93 | boolean[] visit = new boolean[in.length]; 94 | for(int u = 0; u < in.length; ++u) { 95 | if(visit[u] == false) { 96 | dfs(u, in, visit); 97 | //bfs(u, in, visit); 98 | ++count; 99 | } 100 | } 101 | return count; 102 | } 103 | 104 | public static void main(String[] args) { 105 | int n = Integer.parseInt(args[0]); 106 | int[][] in = GraphUtils.randomGraph(n); 107 | GraphUtils.printGraph(in); 108 | System.out.println(countCircles1(in)); 109 | System.out.println(countCircles2(in)); 110 | in = GraphUtils.completeGraph(n); 111 | GraphUtils.printGraph(in); 112 | System.out.println(countCircles1(in)); 113 | System.out.println(countCircles2(in)); 114 | 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /2018-aug/2.advanced-dp problems/src/com/alg/advtop20/dp/MinCutPalPartition.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp; 2 | 3 | import java.util.Arrays; 4 | 5 | class MyInteger { 6 | private int value; 7 | 8 | public MyInteger(int value) { 9 | this.value = value; 10 | } 11 | 12 | public int get() { 13 | return value; 14 | } 15 | 16 | public void set(int value) { 17 | this.value = value; 18 | } 19 | 20 | } 21 | 22 | public class MinCutPalPartition { 23 | 24 | private static boolean isPalindrome(String s) { 25 | for (int i = 0, j = s.length() - 1; i < j; ++i, --j) 26 | if (s.charAt(i) != s.charAt(j)) 27 | return false; 28 | return true; 29 | } 30 | 31 | private static boolean isPalindrome(String s, int i, int j) { 32 | for (; i < j; ++i, --j) 33 | if (s.charAt(i) != s.charAt(j)) 34 | return false; 35 | return true; 36 | } 37 | 38 | private static void auxPartitions1(String in, int depth, MyInteger mincuts, 39 | String path) { 40 | if (in.length() == 1) { 41 | System.out.println(path + "+" + in + ":" + depth); 42 | mincuts.set(Math.min(mincuts.get(), depth)); 43 | return; 44 | } 45 | for (int i = 0; i < in.length(); ++i) { 46 | String tmp = in.substring(0, i + 1); 47 | if (isPalindrome(tmp)) 48 | auxPartitions1(in.substring(i + 1), depth + 1, mincuts, path 49 | + "+" + tmp); 50 | } 51 | } 52 | 53 | // TC:O(n!) SC:O(n) 54 | public static int minCuts1(String s) { 55 | MyInteger mincuts = new MyInteger(Integer.MAX_VALUE); 56 | if (isPalindrome(s)) 57 | return 0; 58 | auxPartitions1(s, 0, mincuts, ""); 59 | return mincuts.get(); 60 | } 61 | 62 | private static int auxCuts2(int i, int j, String s) { 63 | if (i > j || isPalindrome(s, i, j)) 64 | return 0; 65 | int min = Integer.MAX_VALUE; 66 | for (int k = i; k < j; ++k) { 67 | int leftcuts = auxCuts2(i, k, s); 68 | int rightcuts = auxCuts2(k + 1, j, s); 69 | min = Math.min(min, leftcuts + rightcuts + 1); 70 | } 71 | return min; 72 | } 73 | 74 | // TC:min(2 ^ n) SC:O(n) 75 | public static int minCuts2(String s) { 76 | return auxCuts2(0, s.length() - 1, s); 77 | } 78 | 79 | private static void print(int[][] mem) { 80 | for (int[] tmp : mem) 81 | System.out.println(Arrays.toString(tmp)); 82 | } 83 | 84 | // TC:O(n ^ 3) SC:O(n ^ 2) 85 | public static int minCuts3(String s) { 86 | int n = s.length(); 87 | int[][] mem = new int[n][n]; 88 | for (int i = 0; i < n; ++i) 89 | mem[i][i] = 0; 90 | for (int l = 1; l < n; ++l) { 91 | for (int i = 0; i < n - l; ++i) { 92 | int j = i + l; 93 | if (isPalindrome(s, i, j)) 94 | mem[i][j] = 0; 95 | else { 96 | int min = Integer.MAX_VALUE; 97 | for (int k = i; k < j; ++k) { 98 | int leftcuts = mem[i][k]; 99 | int rightcuts = mem[k + 1][j]; 100 | min = Math.min(min, leftcuts + rightcuts + 1); 101 | } 102 | mem[i][j] = min; 103 | } 104 | } 105 | } 106 | print(mem); 107 | return mem[0][n - 1]; 108 | } 109 | 110 | public static void main(String[] args) { 111 | System.out.println(minCuts1(args[0])); 112 | //System.out.println(minCuts2(args[0])); 113 | System.out.println(minCuts3(args[0])); 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/rangequery/oned/RangeSum4.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery.oned; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | class Range { 7 | int l; 8 | int r; 9 | public Range(int l, int r) { 10 | this.l = l; 11 | this.r = r; 12 | } 13 | } 14 | class TreeNode { 15 | Range key; 16 | int sum; 17 | TreeNode left; 18 | TreeNode right; 19 | public TreeNode(int l, int r) { 20 | key = new Range(l, r); 21 | } 22 | public TreeNode(int l, int r, int sum) { 23 | this(l,r); 24 | this.sum = sum; 25 | } 26 | } 27 | class SegmentTree { 28 | private TreeNode root; 29 | 30 | //O(n) 31 | public SegmentTree(int[] in) { 32 | root = build(in, 0, in.length-1); 33 | } 34 | private int get(TreeNode tmp) { 35 | return tmp == null?0:tmp.sum; 36 | } 37 | private TreeNode build(int[] in, int l, int r) { 38 | if(l > r) return null; 39 | if(l == r) return new TreeNode(l, r, in[l]); 40 | int m = l + (r-l)/2; 41 | TreeNode tmp = new TreeNode(l,r); 42 | tmp.left = build(in, l, m); 43 | tmp.right = build(in, m+1, r); 44 | tmp.sum = get(tmp.left) + get(tmp.right); 45 | return tmp; 46 | } 47 | //O(log n) 48 | public void update(int i, int x) { 49 | auxUpdate(root, i, x); 50 | } 51 | private void auxUpdate(TreeNode root, int i, int x) { 52 | //todo: boundary case handling 53 | int m = root.key.l + (root.key.r - root.key.l) / 2; 54 | if(i == root.key.l && i == root.key.r) { 55 | root.sum = x; 56 | return; 57 | } 58 | if(i <= m) 59 | auxUpdate(root.left, i, x); 60 | else 61 | auxUpdate(root.right, i, x); 62 | root.sum = get(root.left) + get(root.right); 63 | } 64 | //O(log n) 65 | public int rangeSum(int i, int j) { 66 | return auxRangeSum(root, i, j); 67 | } 68 | private int auxRangeSum(TreeNode root, int i, int j) { 69 | //todo: boundary case handling 70 | if(root.key.l == i && root.key.r == j) return root.sum; 71 | int m = root.key.l + (root.key.r - root.key.l) / 2; 72 | if(j <= m) 73 | return auxRangeSum(root.left, i, j); 74 | if(i > m) 75 | return auxRangeSum(root.right, i, j); 76 | return auxRangeSum(root.left, i, m) + auxRangeSum(root.right, m+1, j); 77 | } 78 | 79 | public void display() { 80 | auxDisplay(root, 0, 'R'); 81 | } 82 | private void auxDisplay(TreeNode root, int nspaces, char type) { 83 | if(root == null) return; 84 | for(int i = 0; i < nspaces; ++i) 85 | System.out.print(' '); 86 | System.out.println("(" + root.key.l + "," + root.key.r+ "," + root.sum + "," + type + ")"); 87 | auxDisplay(root.left, nspaces + 4, 'L'); 88 | auxDisplay(root.right, nspaces + 4, 'R'); 89 | } 90 | } 91 | public class RangeSum5 { 92 | 93 | public static void main(String[] args) { 94 | int n = Integer.parseInt(args[0]); 95 | int[] in = new int[n]; 96 | Random r = new Random(100); 97 | for(int i = 0; i < n; ++i) 98 | in[i] = r.nextInt(n); 99 | System.out.println(Arrays.toString(in)); 100 | SegmentTree tree = new SegmentTree(in); 101 | tree.display(); 102 | System.out.println(tree.rangeSum(0, n-1)); 103 | System.out.println(tree.rangeSum(1, n-2)); 104 | tree.update(1, -1); 105 | tree.display(); 106 | System.out.println(tree.rangeSum(0, n-1)); 107 | System.out.println(tree.rangeSum(1, n-2)); 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /2018-aug/3.graph-problems/src/com/alg/advtop20/graphs/traversal/countregions/CountRegions.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.traversal.countregions; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | class DisjointSet { 7 | private int[] parent; 8 | private int[] rank; 9 | int nsets; 10 | 11 | public DisjointSet(int[][] in) { 12 | int n = in.length * in.length; 13 | parent = new int[n]; 14 | rank = new int[n]; 15 | for(int i = 0; i < n; ++i) { 16 | parent[i] = i; 17 | rank[i] = 1; 18 | } 19 | for(int i = 0; i < in.length; ++i) { 20 | for(int j = 0; j < in.length; ++j) { 21 | if(in[i][j] == 1) 22 | ++nsets; 23 | } 24 | } 25 | } 26 | 27 | public int find(int x) { 28 | if(parent[x] == x) return x; 29 | return parent[x] = find(parent[x]); 30 | } 31 | 32 | public void union(int x, int y) { 33 | int rx = find(x); 34 | int ry = find(y); 35 | if(rx != ry) { 36 | --nsets; 37 | if(rank[rx] > rank[ry]) 38 | parent[ry] = rx; 39 | else if(rank[ry] > rank[rx]) 40 | parent[rx] = ry; 41 | else { 42 | parent[ry] = rx; 43 | ++rank[rx]; 44 | } 45 | } 46 | } 47 | 48 | public int getNumSets() { 49 | return nsets; 50 | } 51 | 52 | public void display() { 53 | System.out.println(Arrays.toString(parent)); 54 | System.out.println(Arrays.toString(rank)); 55 | } 56 | 57 | } 58 | 59 | 60 | public class CountRegions { 61 | 62 | private static void auxRegions(int i, int j, int[][] in, boolean[][] visit) { 63 | if(i < 0 || i >= in.length || j < 0 || j >= in.length) return; 64 | if(in[i][j] == 0 || visit[i][j] == true) return; 65 | visit[i][j] = true; 66 | auxRegions(i, j-1, in, visit); 67 | auxRegions(i, j+1, in, visit); 68 | auxRegions(i-1, j, in, visit); 69 | auxRegions(i+1, j, in, visit); 70 | } 71 | public static int countRegions1(int[][] in) { 72 | int count = 0; 73 | boolean[][] visit = new boolean[in.length][in.length]; 74 | for(int i = 0; i < in.length; ++i) { 75 | for(int j = 0; j < in.length; ++j) { 76 | if(in[i][j] == 1 && visit[i][j] == false) { 77 | ++count; 78 | auxRegions(i, j, in, visit); 79 | } 80 | } 81 | } 82 | return count; 83 | } 84 | 85 | private static void connect(DisjointSet2 dset, int[][] in, int i1, int j1, int i2, int j2) { 86 | int n = in.length; 87 | if(i2 < 0 || j2 < 0 || in[i2][j2] == 0) return; 88 | dset.union(i1*n+j1, i2*n+j2); 89 | } 90 | public static int countRegions2(int[][] in) { 91 | DisjointSet dset = new DisjointSet(in); 92 | dset.display(); 93 | for(int i = 0; i < in.length; ++i) { 94 | for(int j = 0; j < in.length; ++j) { 95 | if(in[i][j] == 1) { 96 | connect(dset, in, i, j, i-1, j); 97 | connect(dset, in, i, j, i, j-1); 98 | } 99 | } 100 | } 101 | return dset.getNumSets(); 102 | } 103 | 104 | public static void print(int[][] in) { 105 | for(int[] tmp:in) { 106 | System.out.println(Arrays.toString(tmp)); 107 | } 108 | } 109 | 110 | public static void main(String[] args) { 111 | int n = Integer.parseInt(args[0]); 112 | int[][] in = new int[n][n]; 113 | Random r = new Random(100); 114 | for(int k = 1; k <= 2*n; ++k) { 115 | int ri = r.nextInt(n); 116 | int rj = r.nextInt(n); 117 | in[ri][rj] = 1; 118 | } 119 | print(in); 120 | System.out.println(countRegions1(in)); 121 | System.out.println(countRegions2(in)); 122 | 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/quadtree/MXQuadTree.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.quadtree; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | class QuadNode { 7 | Rectangle region; 8 | QuadNode q1, q2, q3, q4; 9 | Integer value; 10 | 11 | public QuadNode(Rectangle region) { 12 | this.region = region; 13 | } 14 | 15 | public QuadNode(Rectangle region, Integer value) { 16 | this.region = region; 17 | this.value = value; 18 | } 19 | 20 | public boolean intersect(Rectangle r) { 21 | if (r.row1 > region.row2 || r.row2 < region.row1 || r.col1 > region.col2 || r.col2 < region.col1) 22 | return false; 23 | return true; 24 | } 25 | 26 | public boolean isLeaf() { 27 | return q1 == null && q2 == null && q3 == null && q4 == null; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return region + ":" + value; 33 | } 34 | 35 | } 36 | 37 | public class MXQuadTree { 38 | private QuadNode root; 39 | 40 | public MXQuadTree(int[][] in) { 41 | root = build(in, new Rectangle(0, 0, in.length - 1, in.length - 1)); 42 | } 43 | 44 | private QuadNode build(int[][] in, Rectangle r) { 45 | if (r.row1 > r.row2 || r.col1 > r.col2) 46 | return null; 47 | if (r.row1 == r.row2 && r.col1 == r.col2) 48 | return new QuadNode(r, in[r.row1][r.col1]); 49 | QuadNode tmp = new QuadNode(r); 50 | int rmid = (r.row1 + r.row2) / 2; 51 | int cmid = (r.col1 + r.col2) / 2; 52 | tmp.q1 = build(in, new Rectangle(r.row1, r.col1, rmid, cmid)); 53 | tmp.q2 = build(in, new Rectangle(r.row1, cmid + 1, rmid, r.col2)); 54 | tmp.q3 = build(in, new Rectangle(rmid + 1, r.col1, r.row2, cmid)); 55 | tmp.q4 = build(in, new Rectangle(rmid + 1, cmid + 1, r.row2, r.col2)); 56 | return tmp; 57 | } 58 | 59 | public void update(int i, int j, int x) { 60 | auxUpdate(root, i, j, x); 61 | } 62 | 63 | private boolean auxUpdate(QuadNode root, int i, int j, int x) { 64 | if (root == null) 65 | return false; 66 | if (i == root.region.row1 && j == root.region.col1 && i == root.region.row2 && j == root.region.col2) { 67 | root.value = x; 68 | return true; 69 | } 70 | if (auxUpdate(root.q1, i, j, x)) 71 | return true; 72 | if (auxUpdate(root.q2, i, j, x)) 73 | return true; 74 | if (auxUpdate(root.q3, i, j, x)) 75 | return true; 76 | return auxUpdate(root.q4, i, j, x); 77 | } 78 | 79 | public List rangeQuery(Rectangle r) { 80 | List values = new ArrayList(); 81 | auxQuery(root, r, values); 82 | return values; 83 | } 84 | 85 | private void auxQuery(QuadNode root, Rectangle r, List values) { 86 | if (root == null || !root.intersect(r)) 87 | return; 88 | if (root.isLeaf()) { 89 | values.add(root.value); 90 | return; 91 | } 92 | auxQuery(root.q1, r, values); 93 | auxQuery(root.q2, r, values); 94 | auxQuery(root.q3, r, values); 95 | auxQuery(root.q4, r, values); 96 | } 97 | 98 | public void display() { 99 | auxDisplay(root, 0, "Root"); 100 | } 101 | 102 | private void auxDisplay(QuadNode root, int nspaces, String type) { 103 | if (root == null) 104 | return; 105 | for (int i = 0; i < nspaces; ++i) 106 | System.out.print(' '); 107 | System.out.println("(" + type + ")" + root); 108 | auxDisplay(root.q1, nspaces + 4, "q1"); 109 | auxDisplay(root.q2, nspaces + 4, "q2"); 110 | auxDisplay(root.q3, nspaces + 4, "q3"); 111 | auxDisplay(root.q4, nspaces + 4, "q4"); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /2018-aug/3.graph-problems/src/com/alg/advtop20/graphs/shortestpaths/ShortestPaths.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.graphs.shortestpaths; 2 | 3 | import com.alg.advtop20.graphs.GraphUtils; 4 | 5 | public class ShortestPaths { 6 | 7 | private static int auxShortestPath1(int[][] in, int s, int t, int k) { 8 | if(s == t) return 0; 9 | if(k == 1) return in[s][t]; 10 | int min = Integer.MAX_VALUE; 11 | for(int i = 0; i < in.length; ++i) { 12 | if(in[i][t] != 0 && in[i][t] != Integer.MAX_VALUE) { 13 | int tmp = auxShortestPath1(in, s, i, k-1); 14 | min = Math.min(min, getSum(in[i][t], tmp)); 15 | } 16 | } 17 | System.out.println(s + " " + t + " " + k + " " + min); 18 | return min; 19 | } 20 | public static int shortestpath1(int[][] in, int s, int t) { 21 | return auxShortestPath1(in, s, t, in.length-1); 22 | } 23 | 24 | private static int getSum(int x, int y) { 25 | if(x == Integer.MAX_VALUE || y == Integer.MAX_VALUE) return Integer.MAX_VALUE; 26 | return x+y; 27 | } 28 | //TC:O(V ^ 3) SC:O(V ^ 2) 29 | public static int shortestpath2(int[][] in, int s, int t) { 30 | int[][] mem = new int[in.length][in.length]; 31 | for(int j = 1; j < in.length; ++j) 32 | mem[s][j] = 0; 33 | for(int i = 1; i < in.length; ++i) 34 | mem[i][1] = in[s][i]; 35 | 36 | for(int j = 2; j < in.length; ++j) { 37 | for(int i = 0; i < in.length; ++i) { 38 | int min = Integer.MAX_VALUE; 39 | for(int v = 0; v < in.length; ++v) 40 | min = Math.min(min, getSum(in[v][i], mem[v][j-1])); 41 | mem[i][j] = min; 42 | } 43 | } 44 | GraphUtils.printGraph(mem); 45 | return mem[t][in.length-1]; 46 | } 47 | 48 | private static int auxShortestPath3(int[][] in, int s, int t, int k) { 49 | if(k == -1) return in[s][t]; 50 | int inclusive = getSum(auxShortestPath3(in, s, k, k-1), auxShortestPath3(in, k, t, k-1)); 51 | int exclusive = auxShortestPath3(in, s, t, k-1); 52 | int min = Math.min(inclusive, exclusive); 53 | System.out.println(s + " " + t + " " + k + " " + min); 54 | return min; 55 | } 56 | public static int shortestpath3(int[][] in, int s, int t) { 57 | return auxShortestPath3(in, s, t, in.length-1); 58 | } 59 | 60 | //TC:O(V ^ 3) SC:O(V ^ 3) 61 | public static int shortestpath4(int[][] in, int s, int t) { 62 | int[][][] mem = new int[in.length+1][in.length][in.length]; 63 | for(int i = 0; i < in.length; ++i) 64 | for(int j = 0; j < in.length; ++j) 65 | mem[0][i][j] = in[i][j]; 66 | GraphUtils.printGraph(mem[0]); 67 | System.out.println(); 68 | 69 | int min = Integer.MAX_VALUE, i, j, k; 70 | for(k = 1; k < in.length; ++k) { 71 | for(i = 0; i < in.length; ++i) { 72 | for(j = 0; j < in.length; ++j) { 73 | int inclusive = getSum(mem[k-1][i][k], mem[k-1][k][j]); 74 | int exclusive = mem[k-1][i][j]; 75 | min = Math.min(inclusive, exclusive); 76 | mem[k][i][j] = min; 77 | } 78 | } 79 | GraphUtils.printGraph(mem[k]); 80 | System.out.println(); 81 | } 82 | 83 | return mem[in.length][s][t]; 84 | } 85 | 86 | public static void main(String[] args) { 87 | int n = Integer.parseInt(args[0]); 88 | int[][] in = GraphUtils.completeWeightedGraph1(n); 89 | GraphUtils.printGraph(in); 90 | /*System.out.println(); 91 | System.out.println(shortestpath1(in, 0, n-1)); 92 | System.out.println(); 93 | System.out.println(shortestpath2(in, 0, n-1)); 94 | System.out.println();*/ 95 | //System.out.println(shortestpath3(in, 0, n-1)); 96 | System.out.println(); 97 | System.out.println(shortestpath4(in, 1, n)); 98 | } 99 | 100 | 101 | 102 | 103 | } 104 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/MinCutPalPartitioning2.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.advdp; 2 | 3 | public class MinCutPalPartitioning2 { 4 | 5 | private static boolean isPalindrome(String s, int i, int j) { 6 | while (i < j) { 7 | if (s.charAt(i) != s.charAt(j)) 8 | return false; 9 | ++i; 10 | --j; 11 | } 12 | return true; 13 | } 14 | 15 | // TC:O(n!) 16 | // SC:O(n) 17 | public static int minCuts1(String in) { 18 | MyInteger gmin = new MyInteger(Integer.MAX_VALUE); 19 | auxCuts1(in, 0, 0, gmin); 20 | return gmin.get(); 21 | } 22 | 23 | private static void auxCuts1(String in, int i, int cuts, MyInteger gmin) { 24 | if (i == in.length() - 1 || isPalindrome(in, i, in.length() - 1)) { 25 | gmin.set(Math.min(gmin.get(), cuts)); 26 | return; 27 | } 28 | for (int j = i; j < in.length() - 1; ++j) { 29 | if (isPalindrome(in, i, j)) 30 | auxCuts1(in, j + 1, cuts + 1, gmin); 31 | } 32 | } 33 | 34 | // TC:O(n!) 35 | // SC:O(n) 36 | public static int minCuts2(String in) { 37 | return auxCuts2(in, 0); 38 | } 39 | 40 | private static int auxCuts2(String in, int i) { 41 | if (i == in.length() - 1 || isPalindrome(in, i, in.length() - 1)) 42 | return 0; 43 | int mincuts = Integer.MAX_VALUE; 44 | for (int j = i; j < in.length() - 1; ++j) { 45 | if (isPalindrome(in, i, j)) { 46 | int res = auxCuts2(in, j + 1); 47 | mincuts = Math.min(mincuts, res); 48 | } 49 | } 50 | return mincuts + 1; 51 | } 52 | 53 | // TC:O(n ^ 3) 54 | // SC:O(n) 55 | public static int minCuts31(String in) { 56 | int[] mem = new int[in.length()]; 57 | return auxCuts31(in, 0, mem); 58 | } 59 | 60 | private static int auxCuts31(String in, int i, int[] mem) { 61 | if (i == in.length() - 1 || isPalindrome(in, i, in.length() - 1)) 62 | return 0; 63 | if (mem[i] != 0) 64 | return mem[i]; 65 | int mincuts = Integer.MAX_VALUE; 66 | for (int j = i; j < in.length() - 1; ++j) { 67 | if (isPalindrome(in, i, j)) { 68 | int res = auxCuts31(in, j + 1, mem); 69 | mincuts = Math.min(mincuts, res); 70 | } 71 | } 72 | return mem[i] = mincuts + 1; 73 | } 74 | 75 | // TC:O(n ^ 3) 76 | // SC:O(n) 77 | public static int minCuts32(String in) { 78 | int n = in.length(); 79 | int[] mem = new int[n]; 80 | mem[n - 1] = 0; 81 | for (int i = n - 2; i >= 0; --i) { 82 | if (isPalindrome(in, i, n - 1)) 83 | mem[i] = 0; 84 | else { 85 | int mincuts = Integer.MAX_VALUE; 86 | for (int j = i; j < n - 1; ++j) { 87 | if (isPalindrome(in, i, j)) 88 | mincuts = Math.min(mincuts, mem[j + 1]); 89 | } 90 | mem[i] = mincuts + 1; 91 | } 92 | } 93 | return mem[0]; 94 | } 95 | 96 | // TC:O(n ^ 2) 97 | // SC:O(n ^ 2) 98 | public static int minCuts33(String in) { 99 | int n = in.length(); 100 | boolean[][] pal = new boolean[n][n]; 101 | for (int i = 0; i < n-1; ++i) { 102 | pal[i][i] = true; 103 | pal[i+1][i] = true; 104 | } 105 | 106 | for (int i = in.length() - 2; i >= 0; --i) { 107 | for (int j = i + 1; j < in.length(); ++j) { 108 | if (in.charAt(i) == in.charAt(j)) 109 | pal[i][j] = pal[i + 1][j - 1]; 110 | else 111 | pal[i][j] = false; 112 | } 113 | } 114 | 115 | int[] mem = new int[n]; 116 | mem[n - 1] = 0; 117 | for (int i = n - 2; i >= 0; --i) { 118 | if (isPalindrome(in, i, n - 1)) 119 | mem[i] = 0; 120 | else { 121 | int mincuts = Integer.MAX_VALUE; 122 | for (int j = i; j < n - 1; ++j) { 123 | if (pal[i][j] == true) 124 | mincuts = Math.min(mincuts, mem[j + 1]); 125 | } 126 | mem[i] = mincuts + 1; 127 | } 128 | } 129 | return mem[0]; 130 | } 131 | 132 | public static void main(String[] args) { 133 | // System.out.println(minCuts1(args[0])); 134 | // System.out.println(minCuts2(args[0])); 135 | System.out.println(minCuts31(args[0])); 136 | System.out.println(minCuts32(args[0])); 137 | System.out.println(minCuts33(args[0])); 138 | 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/dp1/MinCutPalPartitioning2.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp1; 2 | 3 | public class MinCutPalPartitioning2 { 4 | 5 | private static boolean isPalindrome(String s, int i, int j) { 6 | while (i < j) { 7 | if (s.charAt(i) != s.charAt(j)) 8 | return false; 9 | ++i; 10 | --j; 11 | } 12 | return true; 13 | } 14 | 15 | // TC:O(n!) 16 | // SC:O(n) 17 | public static int minCuts1(String in) { 18 | MyInteger gmin = new MyInteger(Integer.MAX_VALUE); 19 | auxCuts1(in, 0, 0, gmin); 20 | return gmin.get(); 21 | } 22 | 23 | private static void auxCuts1(String in, int i, int cuts, MyInteger gmin) { 24 | if (i == in.length() - 1 || isPalindrome(in, i, in.length() - 1)) { 25 | gmin.set(Math.min(gmin.get(), cuts)); 26 | return; 27 | } 28 | for (int j = i; j < in.length() - 1; ++j) { 29 | if (isPalindrome(in, i, j)) 30 | auxCuts1(in, j + 1, cuts + 1, gmin); 31 | } 32 | } 33 | 34 | // TC:O(n!) 35 | // SC:O(n) 36 | public static int minCuts2(String in) { 37 | return auxCuts2(in, 0); 38 | } 39 | 40 | private static int auxCuts2(String in, int i) { 41 | if (i == in.length() - 1 || isPalindrome(in, i, in.length() - 1)) 42 | return 0; 43 | int mincuts = Integer.MAX_VALUE; 44 | for (int j = i; j < in.length() - 1; ++j) { 45 | if (isPalindrome(in, i, j)) { 46 | int res = auxCuts2(in, j + 1); 47 | mincuts = Math.min(mincuts, res); 48 | } 49 | } 50 | return mincuts + 1; 51 | } 52 | 53 | // TC:O(n ^ 3) 54 | // SC:O(n) 55 | public static int minCuts31(String in) { 56 | int[] mem = new int[in.length()]; 57 | return auxCuts31(in, 0, mem); 58 | } 59 | 60 | private static int auxCuts31(String in, int i, int[] mem) { 61 | if (i == in.length() - 1 || isPalindrome(in, i, in.length() - 1)) 62 | return 0; 63 | if (mem[i] != 0) 64 | return mem[i]; 65 | int mincuts = Integer.MAX_VALUE; 66 | for (int j = i; j < in.length() - 1; ++j) { 67 | if (isPalindrome(in, i, j)) { 68 | int res = auxCuts31(in, j + 1, mem); 69 | mincuts = Math.min(mincuts, res); 70 | } 71 | } 72 | return mem[i] = mincuts + 1; 73 | } 74 | 75 | // TC:O(n ^ 3) 76 | // SC:O(n) 77 | public static int minCuts32(String in) { 78 | int n = in.length(); 79 | int[] mem = new int[n]; 80 | mem[n - 1] = 0; 81 | for (int i = n - 2; i >= 0; --i) { 82 | if (isPalindrome(in, i, n - 1)) 83 | mem[i] = 0; 84 | else { 85 | int mincuts = Integer.MAX_VALUE; 86 | for (int j = i; j < n - 1; ++j) { 87 | if (isPalindrome(in, i, j)) 88 | mincuts = Math.min(mincuts, mem[j + 1]); 89 | } 90 | mem[i] = mincuts + 1; 91 | } 92 | } 93 | return mem[0]; 94 | } 95 | 96 | // TC:O(n ^ 2) 97 | // SC:O(n ^ 2) 98 | public static int minCuts33(String in) { 99 | int n = in.length(); 100 | boolean[][] pal = new boolean[n][n]; 101 | for (int i = 0; i < n-1; ++i) { 102 | pal[i][i] = true; 103 | pal[i+1][i] = true; 104 | } 105 | 106 | for (int i = in.length() - 2; i >= 0; --i) { 107 | for (int j = i + 1; j < in.length(); ++j) { 108 | if (in.charAt(i) == in.charAt(j)) 109 | pal[i][j] = pal[i + 1][j - 1]; 110 | else 111 | pal[i][j] = false; 112 | } 113 | } 114 | 115 | int[] mem = new int[n]; 116 | mem[n - 1] = 0; 117 | for (int i = n - 2; i >= 0; --i) { 118 | if (isPalindrome(in, i, n - 1)) 119 | mem[i] = 0; 120 | else { 121 | int mincuts = Integer.MAX_VALUE; 122 | for (int j = i; j < n - 1; ++j) { 123 | if (pal[i][j] == true) 124 | mincuts = Math.min(mincuts, mem[j + 1]); 125 | } 126 | mem[i] = mincuts + 1; 127 | } 128 | } 129 | return mem[0]; 130 | } 131 | 132 | public static void main(String[] args) { 133 | // System.out.println(minCuts1(args[0])); 134 | // System.out.println(minCuts2(args[0])); 135 | System.out.println(minCuts31(args[0])); 136 | System.out.println(minCuts32(args[0])); 137 | System.out.println(minCuts33(args[0])); 138 | 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/RestaurantMerging.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.advdp; 2 | 3 | import java.util.Random; 4 | 5 | public class RestaurantMerging { 6 | 7 | // TC:O(n^n) 8 | // SC:O(n) 9 | public static int merge1(int[] in) { 10 | return auxMerge1(0, in.length - 1, in); 11 | } 12 | 13 | private static int auxMerge1(int i, int j, int[] in) { 14 | if (i == j) 15 | return 0; 16 | int mcost = Integer.MAX_VALUE; 17 | for (int k = i; k < j; ++k) { 18 | int leftMCost = auxMerge1(i, k, in); 19 | int rightMCost = auxMerge1(k + 1, j, in); 20 | int leftSum = 0, rightSum = 0; 21 | for (int tmp = i; tmp <= k; ++tmp) 22 | leftSum += in[tmp]; 23 | for (int tmp = k + 1; tmp <= j; ++tmp) 24 | rightSum += in[tmp]; 25 | int cost = leftMCost + rightMCost + Math.max(leftSum, rightSum); 26 | mcost = Math.min(mcost, cost); 27 | } 28 | return mcost; 29 | } 30 | 31 | // TC:O(n^4) 32 | // SC:O(n^2) 33 | public static int merge21(int[] in) { 34 | int[][] mem = new int[in.length][in.length]; 35 | auxMerge21(0, in.length - 1, in, mem); 36 | // for(int[] tmp: mem) 37 | // System.out.println(Arrays.toString(tmp)); 38 | return mem[0][in.length - 1]; 39 | } 40 | 41 | private static int auxMerge21(int i, int j, int[] in, int[][] mem) { 42 | if (i == j) 43 | return 0; 44 | if (mem[i][j] != 0) 45 | return mem[i][j]; 46 | int mcost = Integer.MAX_VALUE; 47 | for (int k = i; k < j; ++k) { 48 | int leftMCost = auxMerge21(i, k, in, mem); 49 | int rightMCost = auxMerge21(k + 1, j, in, mem); 50 | int leftSum = 0, rightSum = 0; 51 | for (int tmp = i; tmp <= k; ++tmp) 52 | leftSum += in[tmp]; 53 | for (int tmp = k + 1; tmp <= j; ++tmp) 54 | rightSum += in[tmp]; 55 | int cost = leftMCost + rightMCost + Math.max(leftSum, rightSum); 56 | mcost = Math.min(mcost, cost); 57 | } 58 | mem[i][j] = mcost; 59 | return mcost; 60 | } 61 | 62 | // TC:O(n^4) 63 | // SC:O(n^2) 64 | public static int merge22(int[] in) { 65 | int[][] mem = new int[in.length][in.length]; 66 | for (int i = 0; i < in.length; ++i) 67 | mem[i][i] = 0; 68 | for (int i = in.length - 1; i >= 0; --i) { 69 | for (int j = i + 1; j < in.length; ++j) { 70 | int mcost = Integer.MAX_VALUE; 71 | for (int k = i; k < j; ++k) { 72 | int leftMCost = mem[i][k]; 73 | int rightMCost = mem[k + 1][j]; 74 | int leftSum = 0, rightSum = 0; 75 | for (int tmp = i; tmp <= k; ++tmp) 76 | leftSum += in[tmp]; 77 | for (int tmp = k + 1; tmp <= j; ++tmp) 78 | rightSum += in[tmp]; 79 | int cost = leftMCost + rightMCost + Math.max(leftSum, rightSum); 80 | mcost = Math.min(mcost, cost); 81 | } 82 | mem[i][j] = mcost; 83 | } 84 | } 85 | return mem[0][in.length - 1]; 86 | } 87 | 88 | // TC:O(n^3) 89 | // SC:O(n^2) 90 | // DP + cumulative sum for range sum calculations 91 | private static int getSum(int i, int j, int[] csum) { 92 | if(i == 0) return csum[j]; 93 | return csum[j] - csum[i-1]; 94 | } 95 | public static int merge3(int[] in) { 96 | int[] csum = new int[in.length]; 97 | csum[0] = in[0]; 98 | for(int i = 1; i < in.length; ++i) 99 | csum[i] = csum[i-1] + in[i]; 100 | int[][] mem = new int[in.length][in.length]; 101 | for (int i = 0; i < in.length; ++i) 102 | mem[i][i] = 0; 103 | for (int i = in.length - 1; i >= 0; --i) { 104 | for (int j = i + 1; j < in.length; ++j) { 105 | int mcost = Integer.MAX_VALUE; 106 | for (int k = i; k < j; ++k) { 107 | int leftMCost = mem[i][k]; 108 | int rightMCost = mem[k + 1][j]; 109 | int leftSum = getSum(i, k, csum); 110 | int rightSum = getSum(k+1, j, csum); 111 | int cost = leftMCost + rightMCost + Math.max(leftSum, rightSum); 112 | mcost = Math.min(mcost, cost); 113 | } 114 | mem[i][j] = mcost; 115 | } 116 | } 117 | return mem[0][in.length - 1]; 118 | } 119 | 120 | public static void main(String[] args) { 121 | int n = Integer.parseInt(args[0]); 122 | int[] in = new int[n]; 123 | Random r = new Random(); 124 | for (int i = 0; i < n; ++i) 125 | in[i] = r.nextInt(n) + 1; 126 | /// int[] in1 = {1, 3, 2, 5}; 127 | // System.out.println(Arrays.toString(in)); 128 | // System.out.println(merge1(in)); 129 | //System.out.println(merge21(in)); 130 | //System.out.println(merge22(in)); 131 | System.out.println(merge3(in)); 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /2019-december/1.advanced dp/dp1/RestaurantMerging.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.dp1; 2 | 3 | import java.util.Random; 4 | 5 | public class RestaurantMerging { 6 | 7 | // TC:O(n^n) 8 | // SC:O(n) 9 | public static int merge1(int[] in) { 10 | return auxMerge1(0, in.length - 1, in); 11 | } 12 | 13 | private static int auxMerge1(int i, int j, int[] in) { 14 | if (i == j) 15 | return 0; 16 | int mcost = Integer.MAX_VALUE; 17 | for (int k = i; k < j; ++k) { 18 | int leftMCost = auxMerge1(i, k, in); 19 | int rightMCost = auxMerge1(k + 1, j, in); 20 | int leftSum = 0, rightSum = 0; 21 | for (int tmp = i; tmp <= k; ++tmp) 22 | leftSum += in[tmp]; 23 | for (int tmp = k + 1; tmp <= j; ++tmp) 24 | rightSum += in[tmp]; 25 | int cost = leftMCost + rightMCost + Math.max(leftSum, rightSum); 26 | mcost = Math.min(mcost, cost); 27 | } 28 | return mcost; 29 | } 30 | 31 | // TC:O(n^4) 32 | // SC:O(n^2) 33 | public static int merge21(int[] in) { 34 | int[][] mem = new int[in.length][in.length]; 35 | auxMerge21(0, in.length - 1, in, mem); 36 | // for(int[] tmp: mem) 37 | // System.out.println(Arrays.toString(tmp)); 38 | return mem[0][in.length - 1]; 39 | } 40 | 41 | private static int auxMerge21(int i, int j, int[] in, int[][] mem) { 42 | if (i == j) 43 | return 0; 44 | if (mem[i][j] != 0) 45 | return mem[i][j]; 46 | int mcost = Integer.MAX_VALUE; 47 | for (int k = i; k < j; ++k) { 48 | int leftMCost = auxMerge21(i, k, in, mem); 49 | int rightMCost = auxMerge21(k + 1, j, in, mem); 50 | int leftSum = 0, rightSum = 0; 51 | for (int tmp = i; tmp <= k; ++tmp) 52 | leftSum += in[tmp]; 53 | for (int tmp = k + 1; tmp <= j; ++tmp) 54 | rightSum += in[tmp]; 55 | int cost = leftMCost + rightMCost + Math.max(leftSum, rightSum); 56 | mcost = Math.min(mcost, cost); 57 | } 58 | mem[i][j] = mcost; 59 | return mcost; 60 | } 61 | 62 | // TC:O(n^4) 63 | // SC:O(n^2) 64 | public static int merge22(int[] in) { 65 | int[][] mem = new int[in.length][in.length]; 66 | for (int i = 0; i < in.length; ++i) 67 | mem[i][i] = 0; 68 | for (int i = in.length - 1; i >= 0; --i) { 69 | for (int j = i + 1; j < in.length; ++j) { 70 | int mcost = Integer.MAX_VALUE; 71 | for (int k = i; k < j; ++k) { 72 | int leftMCost = mem[i][k]; 73 | int rightMCost = mem[k + 1][j]; 74 | int leftSum = 0, rightSum = 0; 75 | for (int tmp = i; tmp <= k; ++tmp) 76 | leftSum += in[tmp]; 77 | for (int tmp = k + 1; tmp <= j; ++tmp) 78 | rightSum += in[tmp]; 79 | int cost = leftMCost + rightMCost + Math.max(leftSum, rightSum); 80 | mcost = Math.min(mcost, cost); 81 | } 82 | mem[i][j] = mcost; 83 | } 84 | } 85 | return mem[0][in.length - 1]; 86 | } 87 | 88 | // TC:O(n^3) 89 | // SC:O(n^2) 90 | // DP + cumulative sum for range sum calculations 91 | private static int getSum(int i, int j, int[] csum) { 92 | if(i == 0) return csum[j]; 93 | return csum[j] - csum[i-1]; 94 | } 95 | public static int merge3(int[] in) { 96 | int[] csum = new int[in.length]; 97 | csum[0] = in[0]; 98 | for(int i = 1; i < in.length; ++i) 99 | csum[i] = csum[i-1] + in[i]; 100 | int[][] mem = new int[in.length][in.length]; 101 | for (int i = 0; i < in.length; ++i) 102 | mem[i][i] = 0; 103 | for (int i = in.length - 1; i >= 0; --i) { 104 | for (int j = i + 1; j < in.length; ++j) { 105 | int mcost = Integer.MAX_VALUE; 106 | for (int k = i; k < j; ++k) { 107 | int leftMCost = mem[i][k]; 108 | int rightMCost = mem[k + 1][j]; 109 | int leftSum = getSum(i, k, csum); 110 | int rightSum = getSum(k+1, j, csum); 111 | int cost = leftMCost + rightMCost + Math.max(leftSum, rightSum); 112 | mcost = Math.min(mcost, cost); 113 | } 114 | mem[i][j] = mcost; 115 | } 116 | } 117 | return mem[0][in.length - 1]; 118 | } 119 | 120 | public static void main(String[] args) { 121 | int n = Integer.parseInt(args[0]); 122 | int[] in = new int[n]; 123 | Random r = new Random(); 124 | for (int i = 0; i < n; ++i) 125 | in[i] = r.nextInt(n) + 1; 126 | /// int[] in1 = {1, 3, 2, 5}; 127 | // System.out.println(Arrays.toString(in)); 128 | // System.out.println(merge1(in)); 129 | //System.out.println(merge21(in)); 130 | //System.out.println(merge22(in)); 131 | System.out.println(merge3(in)); 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/rangequery/twod/RangeSum4.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery.twod; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | class Rectangle { 7 | int row1; 8 | int col1; 9 | int row2; 10 | int col2; 11 | public Rectangle(int row1, int col1, int row2, int col2) { 12 | super(); 13 | this.row1 = row1; 14 | this.col1 = col1; 15 | this.row2 = row2; 16 | this.col2 = col2; 17 | } 18 | } 19 | class TreeNode { 20 | Rectangle key; 21 | int sum; 22 | TreeNode left, right; 23 | public TreeNode(int row1, int col1, int row2, int col2) { 24 | key = new Rectangle(row1, col1, row2, col2); 25 | } 26 | public TreeNode(int row1, int col1, int row2, int col2, int sum) { 27 | this(row1, col1, row2, col2); 28 | this.sum = sum; 29 | } 30 | } 31 | class KDTree { 32 | private TreeNode root; 33 | 34 | //O(n ^ 2) 35 | public KDTree(int[][] in) { 36 | root = build(in, 0, 0, in.length-1, in.length-1, 1); 37 | } 38 | private int get(TreeNode tmp) { 39 | return tmp == null?0:tmp.sum; 40 | } 41 | private TreeNode build(int[][] in, int row1, int col1, int row2, int col2, int depth) { 42 | if(row1 > row2 || col1 > col2) return null; 43 | if(row1 == row2 && col1 == col2) { 44 | return new TreeNode(row1, col1, row2, col2, in[row1][col1]); 45 | } 46 | TreeNode tmp = new TreeNode(row1, col1, row2, col2); 47 | 48 | if(depth % 2 == 1) { 49 | int cmid = col1 + (col2-col1)/2; 50 | tmp.left = build(in, row1, col1, row2, cmid, depth+1); 51 | tmp.right = build(in, row1, cmid+1, row2, col2, depth+1); 52 | } 53 | else { 54 | int rmid = row1 + (row2-row1)/2; 55 | tmp.left = build(in, row1, col1, rmid, col2, depth+1); 56 | tmp.right = build(in, rmid+1, col1, row2, col2, depth+1); 57 | } 58 | tmp.sum = get(tmp.left) + get(tmp.right); 59 | return tmp; 60 | } 61 | //O(log (2) n^2) 62 | public void update(int i, int j, int x) { 63 | auxUpdate(root, i, j, x, 1); 64 | } 65 | private void auxUpdate(TreeNode root, int i, int j, int x, int depth) { 66 | if(i == root.key.row1 && j == root.key.col1 && i == root.key.row2 && j == root.key.col2) { 67 | root.sum = x; 68 | return; 69 | } 70 | if(depth % 2 == 1) { 71 | int cmid = root.key.col1 + (root.key.col2 - root.key.col1) / 2; 72 | if(j <= cmid) auxUpdate(root.left, i, j, x, depth+1); 73 | else auxUpdate(root.right, i, j, x, depth+1); 74 | } 75 | else { 76 | int rmid = root.key.row1 + (root.key.row2 - root.key.row1) / 2; 77 | if(i <= rmid) auxUpdate(root.left, i, j, x, depth+1); 78 | else auxUpdate(root.right, i, j, x, depth+1); 79 | } 80 | root.sum = get(root.left) + get(root.right); 81 | 82 | } 83 | //O(log (2) n^2) 84 | public int rangeSum(int row1, int col1, int row2, int col2) { 85 | return auxRangeSum(root, row1, col1, row2, col2, 1); 86 | } 87 | private int auxRangeSum(TreeNode root, int row1, int col1, int row2, int col2, int depth) { 88 | if(root.key.row1 == row1 && root.key.col1 == col1 && root.key.row2 == row2 && root.key.col2 == col2) 89 | return root.sum; 90 | if(depth % 2 == 1) { 91 | int cmid = root.key.col1 + (root.key.col2 - root.key.col1) / 2; 92 | if(col2 <= cmid) 93 | return auxRangeSum(root.left, row1, col1, row2, col2, depth+1); 94 | else if(col1 > cmid) 95 | return auxRangeSum(root.right, row1, col1, row2, col2, depth+1); 96 | else 97 | return auxRangeSum(root.left, row1, col1, row2, cmid, depth+1) + auxRangeSum(root.right, row1, cmid+1, row2, col2, depth+1); 98 | } else { 99 | int rmid = root.key.row1 + (root.key.row2 - root.key.row1) / 2; 100 | if(row2 <= rmid) 101 | return auxRangeSum(root.left, row1, col1, row2, col2, depth+1); 102 | else if(row1 > rmid) 103 | return auxRangeSum(root.right, row1, col1, row2, col2, depth+1); 104 | else 105 | return auxRangeSum(root.left, row1, col1, rmid, col2, depth+1) + auxRangeSum(root.right, rmid+1, col1, row2, col2, depth+1); 106 | } 107 | 108 | } 109 | 110 | public void display() { 111 | auxDisplay(root, 0, "Root"); 112 | } 113 | private void auxDisplay(TreeNode root, int nspaces, String type) { 114 | if(root == null) return; 115 | for(int i = 0; i < nspaces; ++i) 116 | System.out.print(' '); 117 | System.out.println("(" + root.key.row1 + "," + root.key.col1 + "," + root.key.row2 + "," + root.key.col2 + "," + root.sum + "," + type + ")"); 118 | auxDisplay(root.left, nspaces + 4, "L"); 119 | auxDisplay(root.right, nspaces + 4, "R"); 120 | } 121 | 122 | } 123 | public class RangeSum4 { 124 | 125 | public static void main(String[] args) { 126 | int n = Integer.parseInt(args[0]); 127 | int[][] in = new int[n][n]; 128 | Random r = new Random(100); 129 | for(int i = 0; i < n; ++i) 130 | for(int j = 0; j < n; ++j) 131 | in[i][j] = r.nextInt(n); 132 | for(int[] tmp:in) 133 | System.out.println(Arrays.toString(tmp)); 134 | KDTree tree = new KDTree(in); 135 | tree.display(); 136 | System.out.println(tree.rangeSum(0, 0, n-1,n-1)); 137 | System.out.println(tree.rangeSum(1, 1, n-2,n-2)); 138 | System.out.println(); 139 | tree.update(1,1, -1); 140 | tree.display(); 141 | System.out.println(tree.rangeSum(0, 0, n-1,n-1)); 142 | System.out.println(tree.rangeSum(1, 1, n-2,n-2)); 143 | } 144 | 145 | } 146 | 147 | 148 | -------------------------------------------------------------------------------- /2018-aug/1.range-query problems/src/com/alg/advtop20/rangequery/twod/RangeSum3.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.rangequery.twod; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | class Rectangle { 7 | int row1; 8 | int col1; 9 | int row2; 10 | int col2; 11 | public Rectangle(int row1, int col1, int row2, int col2) { 12 | super(); 13 | this.row1 = row1; 14 | this.col1 = col1; 15 | this.row2 = row2; 16 | this.col2 = col2; 17 | } 18 | } 19 | class QuadNode { 20 | Rectangle key; 21 | int sum; 22 | QuadNode q1, q2, q3, q4; 23 | public QuadNode(int row1, int col1, int row2, int col2) { 24 | key = new Rectangle(row1, col1, row2, col2); 25 | } 26 | public QuadNode(int row1, int col1, int row2, int col2, int sum) { 27 | this(row1, col1, row2, col2); 28 | this.sum = sum; 29 | } 30 | } 31 | class QuadTree { 32 | private QuadNode root; 33 | 34 | //O(n ^ 2) 35 | public QuadTree(int[][] in) { 36 | root = build(in, 0, 0, in.length-1, in.length-1); 37 | } 38 | private int get(QuadNode tmp) { 39 | return tmp == null?0:tmp.sum; 40 | } 41 | private QuadNode build(int[][] in, int row1, int col1, int row2, int col2) { 42 | if(row1 > row2 || col1 > col2) return null; 43 | if(row1 == row2 && col1 == col2) return new QuadNode(row1, col1, row2, col2, in[row1][col1]); 44 | int rmid = row1 + (row2-row1)/2; 45 | int cmid = col1 + (col2-col1)/2; 46 | QuadNode tmp = new QuadNode(row1, col1, row2, col2); 47 | tmp.q1 = build(in, row1, col1, rmid, cmid); 48 | tmp.q2= build(in, row1, cmid+1, rmid, col2); 49 | tmp.q3 = build(in, rmid+1, col1, row2, cmid); 50 | tmp.q4= build(in, rmid+1, cmid+1, row2, col2); 51 | tmp.sum = get(tmp.q1) + get(tmp.q2) + get(tmp.q3) + get(tmp.q4); 52 | return tmp; 53 | } 54 | //O(log (4) n^2) 55 | public void update(int i, int j, int x) { 56 | auxUpdate(root, i, j, x); 57 | } 58 | private void auxUpdate(QuadNode root, int i, int j, int x) { 59 | int rmid = root.key.row1 + (root.key.row2-root.key.row1)/2; 60 | int cmid = root.key.col1 + (root.key.col2-root.key.col1)/2; 61 | if(i == root.key.row1 && j == root.key.col1 && i == root.key.row2 && j == root.key.col2) { 62 | root.sum = x; 63 | return; 64 | } 65 | if(i <= rmid) { 66 | if(j <= cmid) auxUpdate(root.q1, i, j, x); 67 | else auxUpdate(root.q2, i, j, x); 68 | } 69 | else { 70 | if(j <= cmid) auxUpdate(root.q3, i, j, x); 71 | else auxUpdate(root.q4, i, j, x); 72 | } 73 | root.sum = get(root.q1) + get(root.q2) + get(root.q3) + get(root.q4); 74 | 75 | } 76 | //O(log (4) n^2) 77 | public int rangeSum(int row1, int col1, int row2, int col2) { 78 | return auxRangeSum(root, row1, col1, row2, col2); 79 | } 80 | private int auxRangeSum(QuadNode root, int row1, int col1, int row2, int col2) { 81 | if(root.key.row1 == row1 && root.key.col1 == col1 && root.key.row2 == row2 && root.key.col2 == col2) 82 | return root.sum; 83 | int rmid = root.key.row1 + (root.key.row2-root.key.row1)/2; 84 | int cmid = root.key.col1 + (root.key.col2-root.key.col1)/2; 85 | 86 | if(row2 <= rmid) { 87 | if(col2 <= cmid) return auxRangeSum(root.q1, row1, col1, row2, col2); 88 | else if(col1 > cmid) return auxRangeSum(root.q2, row1, col1, row2, col2); 89 | else return auxRangeSum(root.q1, row1, col1, row2, cmid) + auxRangeSum(root.q2, row1, cmid+1, row2, col2); 90 | } 91 | else if(row1 > rmid){ 92 | if(col2 <= cmid) return auxRangeSum(root.q3, row1, col1, row2, col2); 93 | else if(col1 > cmid) return auxRangeSum(root.q4, row1, col1, row2, col2); 94 | else return auxRangeSum(root.q3, row1, col1, row2, cmid) + auxRangeSum(root.q4, row1, cmid+1, row2, col2); 95 | } else if(col2 <= cmid) { 96 | return auxRangeSum(root.q1, row1, col1, rmid, col2) + auxRangeSum(root.q3, rmid+1, col1, row2, col2); 97 | } else if(col1 > cmid) { 98 | return auxRangeSum(root.q2, row1, col1, rmid, col2) + auxRangeSum(root.q4, rmid+1, col1, row2, col2); 99 | } else { 100 | return auxRangeSum(root.q1, row1, col1, rmid, cmid) + auxRangeSum(root.q2, row1, cmid+1, rmid, col2) 101 | + auxRangeSum(root.q3, rmid+1, col1, row2, cmid) + auxRangeSum(root.q4, rmid+1, cmid+1, row2, col2); 102 | } 103 | } 104 | 105 | public void display() { 106 | auxDisplay(root, 0, "R"); 107 | } 108 | private void auxDisplay(QuadNode root, int nspaces, String type) { 109 | if(root == null) return; 110 | for(int i = 0; i < nspaces; ++i) 111 | System.out.print(' '); 112 | System.out.println("(" + root.key.row1 + "," + root.key.col1 + "," + root.key.row2 + "," + root.key.col2 + "," + root.sum + "," + type + ")"); 113 | auxDisplay(root.q1, nspaces + 4, "q1"); 114 | auxDisplay(root.q2, nspaces + 4, "q2"); 115 | auxDisplay(root.q3, nspaces + 4, "q3"); 116 | auxDisplay(root.q4, nspaces + 4, "q4"); 117 | } 118 | } 119 | 120 | public class RangeSum3 { 121 | public static void main(String[] args) { 122 | int n = Integer.parseInt(args[0]); 123 | int[][] in = new int[n][n]; 124 | Random r = new Random(100); 125 | for(int i = 0; i < n; ++i) 126 | for(int j = 0; j < n; ++j) 127 | in[i][j] = r.nextInt(n); 128 | for(int[] tmp:in) 129 | System.out.println(Arrays.toString(tmp)); 130 | QuadTree tree = new QuadTree(in); 131 | tree.display(); 132 | tree.update(1,1, -1); 133 | for(int[] tmp:in) 134 | System.out.println(Arrays.toString(tmp)); 135 | tree.display(); 136 | System.out.println(tree.rangeSum(1, 1, n-2, n-2)); 137 | System.out.println(tree.rangeSum(0, 0, n-1, 0)); 138 | System.out.println(tree.rangeSum(0, n-1, n-1, n-1)); 139 | System.out.println(tree.rangeSum(0, 0, 0, n-1)); 140 | 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /2019-december/3.range query problems/src/com/alg/advtop20/quadtree/PRQuadTree.java: -------------------------------------------------------------------------------- 1 | package com.alg.advtop20.quadtree; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | class Rectangle { 7 | int row1, col1, row2, col2; 8 | 9 | public Rectangle(int row1, int col1, int row2, int col2) { 10 | super(); 11 | this.row1 = row1; 12 | this.col1 = col1; 13 | this.row2 = row2; 14 | this.col2 = col2; 15 | } 16 | 17 | public boolean contains(Point p) { 18 | if (p.x >= col1 && p.x <= col2 && p.y >= row1 && p.y <= row2) 19 | return true; 20 | return false; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return "Rectangle [row1=" + row1 + ", col1=" + col1 + ", row2=" + row2 + ", col2=" + col2 + "]"; 26 | } 27 | 28 | } 29 | 30 | class Point { 31 | int x, y; 32 | 33 | public Point(int x, int y) { 34 | this.x = x; 35 | this.y = y; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object obj) { 40 | Point p = (Point) obj; 41 | return this.x == p.x && this.y == p.y; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "Point [y=" + y + ", x=" + x + "]"; 47 | } 48 | 49 | } 50 | 51 | class PRQuadNode { 52 | Rectangle region; 53 | List points; 54 | PRQuadNode q1, q2, q3, q4; 55 | 56 | public PRQuadNode(Rectangle region) { 57 | this.region = region; 58 | this.points = new ArrayList(); 59 | } 60 | 61 | public PRQuadNode(Rectangle region, List points) { 62 | this.region = region; 63 | this.points = points; 64 | } 65 | 66 | public boolean contains(Point p) { 67 | return region.contains(p); 68 | } 69 | 70 | // split and distribute points across 4 children 71 | public void split() { 72 | int rmid = (region.row1 + region.row2) / 2; 73 | int cmid = (region.col1 + region.col2) / 2; 74 | 75 | Rectangle r1 = new Rectangle(region.row1, region.col1, rmid, cmid); 76 | Rectangle r2 = new Rectangle(region.row1, cmid + 1, rmid, region.col2); 77 | Rectangle r3 = new Rectangle(rmid + 1, region.col1, region.row2, cmid); 78 | Rectangle r4 = new Rectangle(rmid + 1, cmid + 1, region.row2, region.col2); 79 | List p1 = new ArrayList(); 80 | List p2 = new ArrayList(); 81 | List p3 = new ArrayList(); 82 | List p4 = new ArrayList(); 83 | 84 | for (Point point : points) { 85 | if (r1.contains(point)) 86 | p1.add(point); 87 | else if (r2.contains(point)) 88 | p2.add(point); 89 | else if (r3.contains(point)) 90 | p3.add(point); 91 | else 92 | p4.add(point); 93 | } 94 | q1 = new PRQuadNode(r1, p1); 95 | q2 = new PRQuadNode(r2, p2); 96 | q3 = new PRQuadNode(r3, p3); 97 | q4 = new PRQuadNode(r4, p4); 98 | points = null; 99 | 100 | } 101 | 102 | public boolean isLeaf() { 103 | return q1 == null && q2 == null && q3 == null && q4 == null; 104 | } 105 | 106 | @Override 107 | public String toString() { 108 | return region + ":" + points; 109 | } 110 | 111 | public boolean intersect(Rectangle r) { 112 | if (r.row1 > region.row2 || r.row2 < region.row1 || r.col1 > region.col2 || r.col2 < region.col1) 113 | return false; 114 | return true; 115 | } 116 | } 117 | 118 | public class PRQuadTree { 119 | private PRQuadNode root; 120 | public static int MAX_POINTS_PER_REGION = 10; 121 | 122 | public PRQuadTree(Rectangle region) { 123 | root = new PRQuadNode(region); 124 | } 125 | 126 | public PRQuadTree(Rectangle region, int max_points) { 127 | root = new PRQuadNode(region); 128 | MAX_POINTS_PER_REGION = max_points; 129 | } 130 | 131 | public void add(Point point) { 132 | auxAdd(root, point); 133 | } 134 | 135 | private boolean auxAdd(PRQuadNode root, Point p) { 136 | if (root.isLeaf()) { 137 | if (!root.contains(p)) 138 | return false; 139 | // add the point if current node can accommodate 140 | if (root.points.size() < PRQuadTree.MAX_POINTS_PER_REGION) { 141 | root.points.add(p); 142 | return true; 143 | } 144 | root.split(); 145 | } 146 | 147 | if (auxAdd(root.q1, p)) 148 | return true; 149 | if (auxAdd(root.q2, p)) 150 | return true; 151 | if (auxAdd(root.q3, p)) 152 | return true; 153 | return auxAdd(root.q4, p); 154 | } 155 | 156 | public List rangeQuery(Rectangle r) { 157 | List points = new ArrayList(); 158 | auxQuery(root, r, points); 159 | return points; 160 | } 161 | 162 | private void auxQuery(PRQuadNode root, Rectangle r, List points) { 163 | if (root == null || !root.intersect(r)) 164 | return; 165 | if (root.isLeaf()) { 166 | for (Point point : root.points) 167 | if (r.contains(point)) 168 | points.add(point); 169 | return; 170 | } 171 | auxQuery(root.q1, r, points); 172 | auxQuery(root.q2, r, points); 173 | auxQuery(root.q3, r, points); 174 | auxQuery(root.q4, r, points); 175 | } 176 | 177 | public List kNearestNeighbors(Point p, int k) { 178 | List points = new ArrayList(); 179 | return points; 180 | } 181 | 182 | public void display() { 183 | auxDisplay(root, 0, "Root"); 184 | } 185 | 186 | private void auxDisplay(PRQuadNode root, int nspaces, String type) { 187 | if (root == null) 188 | return; 189 | for (int i = 0; i < nspaces; ++i) 190 | System.out.print(' '); 191 | System.out.println("(" + type + ")" + root); 192 | auxDisplay(root.q1, nspaces + 4, "q1"); 193 | auxDisplay(root.q2, nspaces + 4, "q2"); 194 | auxDisplay(root.q3, nspaces + 4, "q3"); 195 | auxDisplay(root.q4, nspaces + 4, "q4"); 196 | } 197 | } 198 | --------------------------------------------------------------------------------