Yesterday I did the Biweekly Contest, and today I did the regular contest plus Google Kick Start Round D in the afternoon. Three contests in a row made for a very full weekend.
1137. N-th Tribonacci Number
Similar to Fibonacci. The same solutions should all work here. I used the solution that was the easiest to implement.
This is also a straightforward solution. Because the movement distance is just the Manhattan distance between two points, greedily moving is enough. There is a pitfall here: from the position of z, you cannot move right, and from uvwxy, you cannot move down.
classSolution { public: string alphabetBoardPath(string target){ vector<pair<int, int>> locations(26); for (char c = 'a'; c <= 'z'; ++c) { int index = c - 'a'; locations[index] = {index / 5, index % 5}; } pair<int,int> current = {0, 0}; string ans; auto special = locations.back(); for (char c : target) { auto to = locations[c - 'a']; if (current != special) { if (to.second > current.second) { ans.append(to.second - current.second, 'R'); } else { ans.append(current.second - to.second, 'L'); } if (to.first > current.first) { ans.append(to.first - current.first, 'D'); } else { ans.append(current.first - to.first, 'U'); } } else { if (to.first > current.first) { ans.append(to.first - current.first, 'D'); } else { ans.append(current.first - to.first, 'U'); } if (to.second > current.second) { ans.append(to.second - current.second, 'R'); } else { ans.append(current.second - to.second, 'L'); } } ans.push_back('!'); current = to; } return ans; } };
1139. Largest 1-Bordered Square
I had done a similar problem before; the difference was that the square was solid. This problem is similar. Enumerate every possible bottom-right corner of the square, then enumerate every possible top-left corner and check whether they can form a valid square.
Time complexity: O(N ^ 3) Space complexity: O(N ^ 2)
classSolution { public: intlargest1BorderedSquare(vector<vector<int>>& grid){ auto up = grid, down = grid, left = grid, right = grid; constint R = grid.size(), C = grid[0].size(); for (int i = 0; i < R; ++i) { for (int j = 0; j < C; ++j) { if (i == 0) { up[i][j] = grid[i][j] == 1 ? 1 : 0; } else { up[i][j] = grid[i][j] == 1 ? up[i-1][j] + 1 : 0; } if (j == 0) { left[i][j] = grid[i][j] == 1 ? 1 : 0; } else { left[i][j] = grid[i][j] == 1 ? left[i][j-1] + 1 : 0; } } } for (int i = R - 1; i >= 0; --i) { for (int j = C - 1; j >= 0; --j) { if (i == R - 1) { down[i][j] = grid[i][j] == 1 ? 1 : 0; } else { down[i][j] = grid[i][j] == 1 ? down[i+1][j] + 1 : 0; } if (j == C - 1) { right[i][j] = grid[i][j] == 1 ? 1 : 0; } else { right[i][j] = grid[i][j] == 1 ? right[i][j+1] + 1 : 0; } } } int ans = 0; for (int i = 0; i < R; ++i) { for (int j = 0; j < C; ++j) { for (int k = min(up[i][j], left[i][j]); k > ans; --k) { int corner_i = i - k + 1; int corner_j = j - k + 1; if (down[corner_i][corner_j] >= k && right[corner_i][corner_j] >= k) { ans = k; break; } } } } return ans * ans; } };
1140. Stone Game II
The regular idea is DP. Here I used a top-down memoization style, which is easier to implement. State transition equation: dp[begin][M] = max(sum of prefix + sum of suffix - dp[begin + X][max(X, M)]), for X in [1, 2 * M].
Time complexity: O(N^2), Space complexity: O(N^2).