|
| 1 | +package com.fishercoder.solutions; |
| 2 | + |
| 3 | +import java.util.*; |
| 4 | + |
| 5 | +/** |
| 6 | + * 631. Design Excel Sum Formula |
| 7 | + * |
| 8 | + * Your task is to design the basic function of Excel and implement the function of sum formula. |
| 9 | + * Specifically, you need to implement the following functions: |
| 10 | +
|
| 11 | + Excel(int H, char W): |
| 12 | + This is the constructor. |
| 13 | + The inputs represents the height and width of the Excel form. |
| 14 | + H is a positive integer, range from 1 to 26. |
| 15 | + It represents the height. |
| 16 | + W is a character range from 'A' to 'Z'. |
| 17 | + It represents that the width is the number of characters from 'A' to W. |
| 18 | + The Excel form content is represented by a height * width 2D integer array C, it should be initialized to zero. |
| 19 | + You should assume that the first row of C starts from 1, and the first column of C starts from 'A'. |
| 20 | +
|
| 21 | + void Set(int row, char column, int val): |
| 22 | + Change the value at C(row, column) to be val. |
| 23 | +
|
| 24 | + int Get(int row, char column): |
| 25 | + Return the value at C(row, column). |
| 26 | +
|
| 27 | + int Sum(int row, char column, List of Strings : numbers): |
| 28 | + This function calculate and set the value at C(row, column), |
| 29 | + where the value should be the sum of cells represented by numbers. |
| 30 | + This function return the sum result at C(row, column). |
| 31 | + This sum formula should exist until this cell is overlapped by another value or another sum formula. |
| 32 | +
|
| 33 | + numbers is a list of strings that each string represent a cell or a range of cells. |
| 34 | + If the string represent a single cell, |
| 35 | + then it has the following format : ColRow. For example, "F7" represents the cell at (7, F). |
| 36 | + If the string represent a range of cells, |
| 37 | + then it has the following format : ColRow1:ColRow2. |
| 38 | + The range will always be a rectangle, |
| 39 | + and ColRow1 represent the position of the top-left cell, |
| 40 | + and ColRow2 represents the position of the bottom-right cell. |
| 41 | +
|
| 42 | +
|
| 43 | + Example 1: |
| 44 | + Excel(3,"C"); |
| 45 | + // construct a 3*3 2D array with all zero. |
| 46 | + // A B C |
| 47 | + // 1 0 0 0 |
| 48 | + // 2 0 0 0 |
| 49 | + // 3 0 0 0 |
| 50 | +
|
| 51 | + Set(1, "A", 2); |
| 52 | + // set C(1,"A") to be 2. |
| 53 | + // A B C |
| 54 | + // 1 2 0 0 |
| 55 | + // 2 0 0 0 |
| 56 | + // 3 0 0 0 |
| 57 | +
|
| 58 | + Sum(3, "C", ["A1", "A1:B2"]); |
| 59 | + // set C(3,"C") to be the sum of value at C(1,"A") |
| 60 | + //and the values sum of the rectangle range whose top-left cell is C(1,"A") and bottom-right cell is C(2,"B"). Return 4. |
| 61 | + // A B C |
| 62 | + // 1 2 0 0 |
| 63 | + // 2 0 0 0 |
| 64 | + // 3 0 0 4 |
| 65 | +
|
| 66 | + Set(2, "B", 2); |
| 67 | + // set C(2,"B") to be 2. Note C(3, "C") should also be changed. |
| 68 | + // A B C |
| 69 | + // 1 2 0 0 |
| 70 | + // 2 0 2 0 |
| 71 | + // 3 0 0 6 |
| 72 | +
|
| 73 | + Note: |
| 74 | + You could assume that there won't be any circular sum reference. |
| 75 | + For example, A1 = sum(B1) and B1 = sum(A1). |
| 76 | + The test cases are using double-quotes to represent a character. |
| 77 | + Please remember to RESET your class variables declared in class Excel, |
| 78 | + as static/class variables are persisted across multiple test cases. Please see here for more details. |
| 79 | + */ |
| 80 | +public class _631 { |
| 81 | + |
| 82 | + /**Credit: https://leetcode.com/articles/design-excel-sum-formula/#approach-1-using-topological-sortaccepted*/ |
| 83 | + public static class Excel { |
| 84 | + |
| 85 | + Formula[][] Formulas; |
| 86 | + |
| 87 | + class Formula { |
| 88 | + Formula(HashMap<String, Integer> c, int v) { |
| 89 | + val = v; |
| 90 | + cells = c; |
| 91 | + } |
| 92 | + |
| 93 | + HashMap<String, Integer> cells; |
| 94 | + int val; |
| 95 | + } |
| 96 | + |
| 97 | + Stack<int[]> stack = new Stack<>(); |
| 98 | + |
| 99 | + public Excel(int H, char W) { |
| 100 | + Formulas = new Formula[H][(W - 'A') + 1]; |
| 101 | + } |
| 102 | + |
| 103 | + public int get(int r, char c) { |
| 104 | + if (Formulas[r - 1][c - 'A'] == null) { |
| 105 | + return 0; |
| 106 | + } |
| 107 | + return Formulas[r - 1][c - 'A'].val; |
| 108 | + } |
| 109 | + |
| 110 | + public void set(int r, char c, int v) { |
| 111 | + Formulas[r - 1][c - 'A'] = new Formula(new HashMap<String, Integer>(), v); |
| 112 | + topologicalSort(r - 1, c - 'A'); |
| 113 | + execute_stack(); |
| 114 | + } |
| 115 | + |
| 116 | + public int sum(int r, char c, String[] strs) { |
| 117 | + HashMap<String, Integer> cells = convert(strs); |
| 118 | + int summ = calculate_sum(r - 1, c - 'A', cells); |
| 119 | + set(r, c, summ); |
| 120 | + Formulas[r - 1][c - 'A'] = new Formula(cells, summ); |
| 121 | + return summ; |
| 122 | + } |
| 123 | + |
| 124 | + public void topologicalSort(int r, int c) { |
| 125 | + for (int i = 0; i < Formulas.length; i++) |
| 126 | + for (int j = 0; j < Formulas[0].length; j++) |
| 127 | + if (Formulas[i][j] != null && Formulas[i][j].cells.containsKey("" + (char) ('A' + c) + (r + 1))) { |
| 128 | + topologicalSort(i, j); |
| 129 | + } |
| 130 | + stack.push(new int[]{r, c}); |
| 131 | + } |
| 132 | + |
| 133 | + public void execute_stack() { |
| 134 | + while (!stack.isEmpty()) { |
| 135 | + int[] top = stack.pop(); |
| 136 | + if (Formulas[top[0]][top[1]].cells.size() > 0) { |
| 137 | + calculate_sum(top[0], top[1], Formulas[top[0]][top[1]].cells); |
| 138 | + } |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | + public HashMap<String, Integer> convert(String[] strs) { |
| 143 | + HashMap<String, Integer> res = new HashMap<>(); |
| 144 | + for (String st : strs) { |
| 145 | + if (st.indexOf(":") < 0) { |
| 146 | + res.put(st, res.getOrDefault(st, 0) + 1); |
| 147 | + } |
| 148 | + else { |
| 149 | + String[] cells = st.split(":"); |
| 150 | + int si = Integer.parseInt(cells[0].substring(1)), ei = Integer.parseInt(cells[1].substring(1)); |
| 151 | + char sj = cells[0].charAt(0), ej = cells[1].charAt(0); |
| 152 | + for (int i = si; i <= ei; i++) { |
| 153 | + for (char j = sj; j <= ej; j++) { |
| 154 | + res.put("" + j + i, res.getOrDefault("" + j + i, 0) + 1); |
| 155 | + } |
| 156 | + } |
| 157 | + } |
| 158 | + } |
| 159 | + return res; |
| 160 | + } |
| 161 | + |
| 162 | + public int calculate_sum(int r, int c, HashMap<String, Integer> cells) { |
| 163 | + int sum = 0; |
| 164 | + for (String s : cells.keySet()) { |
| 165 | + int x = Integer.parseInt(s.substring(1)) - 1, y = s.charAt(0) - 'A'; |
| 166 | + sum += (Formulas[x][y] != null ? Formulas[x][y].val : 0) * cells.get(s); |
| 167 | + } |
| 168 | + Formulas[r][c] = new Formula(cells, sum); |
| 169 | + return sum; |
| 170 | + } |
| 171 | + } |
| 172 | + |
| 173 | + /** |
| 174 | + * Your Excel object will be instantiated and called as such: |
| 175 | + * Excel obj = new Excel(H, W); |
| 176 | + * obj.set(r,c,v); |
| 177 | + * int param_2 = obj.get(r,c); |
| 178 | + * int param_3 = obj.sum(r,c,strs); |
| 179 | + */ |
| 180 | + |
| 181 | + public static void main(String... args) { |
| 182 | + System.out.println('A' - 64); |
| 183 | + System.out.println((int) 'C'); |
| 184 | + System.out.println('Z' - 64); |
| 185 | + } |
| 186 | +} |
0 commit comments