Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/main/java/g2201_2300/s2266_count_number_of_texts/Solution.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package g2201_2300.s2266_count_number_of_texts;

// #Medium #Hash_Table #Math #String #Dynamic_Programming
// #2022_06_15_Time_38_ms_(81.43%)_Space_51.2_MB_(80.48%)

@SuppressWarnings("java:S135")
public class Solution {
public int countTexts(String pressedKeys) {
int len = pressedKeys.length();
long dp0 = 1L;
long dp1 = 0;
long dp2 = 0;
long dp3 = 0;
long dp4;
char[] keys = pressedKeys.toCharArray();
int base = 1000000007;
for (int i = 1; i < len; i++) {
int r = keys[i] - '0';
dp4 = dp3;
dp3 = dp2;
dp2 = dp1;
dp1 = dp0 % base;
dp0 = dp1;
dp0 += (i - 1 == 0 && keys[i] == keys[i - 1]) ? 1 : 0;
if (i - 1 <= 0 || keys[i] != keys[i - 1]) {
continue;
}
dp0 += dp2;
dp0 += (i - 2 == 0 && keys[i] == keys[i - 2]) ? 1 : 0;
if (i - 2 <= 0 || keys[i] != keys[i - 2]) {
continue;
}
dp0 += dp3;
dp0 += (i - 3 == 0 && keys[i] == keys[i - 3] && (r == 7 || r == 9)) ? 1 : 0;
if (i - 3 <= 0 || keys[i] != keys[i - 3] || (r != 7 && r != 9)) {
continue;
}
dp0 += dp4;
}

return (int) (dp0 % base);
}
}
49 changes: 49 additions & 0 deletions src/main/java/g2201_2300/s2266_count_number_of_texts/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
2266\. Count Number of Texts

Medium

Alice is texting Bob using her phone. The **mapping** of digits to letters is shown in the figure below.

![](https://assets.leetcode.com/uploads/2022/03/15/1200px-telephone-keypad2svg.png)

In order to **add** a letter, Alice has to **press** the key of the corresponding digit `i` times, where `i` is the position of the letter in the key.

* For example, to add the letter `'s'`, Alice has to press `'7'` four times. Similarly, to add the letter `'k'`, Alice has to press `'5'` twice.
* Note that the digits `'0'` and `'1'` do not map to any letters, so Alice **does not** use them.

However, due to an error in transmission, Bob did not receive Alice's text message but received a **string of pressed keys** instead.

* For example, when Alice sent the message `"bob"`, Bob received the string `"2266622"`.

Given a string `pressedKeys` representing the string received by Bob, return _the **total number of possible text messages** Alice could have sent_.

Since the answer may be very large, return it **modulo** <code>10<sup>9</sup> + 7</code>.

**Example 1:**

**Input:** pressedKeys = "22233"

**Output:** 8

**Explanation:**

The possible text messages Alice could have sent are:

"aaadd", "abdd", "badd", "cdd", "aaae", "abe", "bae", and "ce".

Since there are 8 possible messages, we return 8.

**Example 2:**

**Input:** pressedKeys = "222222222222222222222222222222222222"

**Output:** 82876089

**Explanation:** There are 2082876103 possible text messages Alice could have sent.

Since we need to return the answer modulo 10<sup>9</sup> + 7, we return 2082876103 % (10<sup>9</sup> + 7) = 82876089.

**Constraints:**

* <code>1 <= pressedKeys.length <= 10<sup>5</sup></code>
* `pressedKeys` only consists of digits from `'2'` - `'9'`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package g2201_2300.s2267_check_if_there_is_a_valid_parentheses_string_path;

// #Hard #Array #Dynamic_Programming #Matrix
// #2022_06_15_Time_93_ms_(77.48%)_Space_128.2_MB_(27.18%)

public class Solution {
private char[][] grid;
private int m;
private int n;
private static final char LFTPAR = '(';
private static final char RGTPAR = ')';

public boolean hasValidPath(char[][] grid) {
this.grid = grid;
this.m = grid.length;
this.n = grid[0].length;
Boolean[][][] dp = new Boolean[m][n][m + n + 1];
if (grid[0][0] == RGTPAR) {
return false;
}
if ((m + n) % 2 == 0) {
return false;
}
return dfs(0, 0, 0, 0, dp);
}

private boolean dfs(int u, int v, int open, int close, Boolean[][][] dp) {
if (grid[u][v] == LFTPAR) {
open++;
} else {
close++;
}
if (u == m - 1 && v == n - 1) {
return open == close;
}
if (open < close) {
return false;
}
if (dp[u][v][open - close] != null) {
return dp[u][v][open - close];
}
if (u == m - 1) {
boolean result = dfs(u, v + 1, open, close, dp);
dp[u][v][open - close] = result;
return result;
}
if (v == n - 1) {
return dfs(u + 1, v, open, close, dp);
}
boolean rslt = false;
if (grid[u][v] == LFTPAR) {
rslt = dfs(u + 1, v, open, close, dp) || dfs(u, v + 1, open, close, dp);
} else {
rslt = dfs(u, v + 1, open, close, dp) || dfs(u + 1, v, open, close, dp);
}
dp[u][v][open - close] = rslt;
return rslt;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
2267\. Check if There Is a Valid Parentheses String Path

Hard

A parentheses string is a **non-empty** string consisting only of `'('` and `')'`. It is **valid** if **any** of the following conditions is **true**:

* It is `()`.
* It can be written as `AB` (`A` concatenated with `B`), where `A` and `B` are valid parentheses strings.
* It can be written as `(A)`, where `A` is a valid parentheses string.

You are given an `m x n` matrix of parentheses `grid`. A **valid parentheses string path** in the grid is a path satisfying **all** of the following conditions:

* The path starts from the upper left cell `(0, 0)`.
* The path ends at the bottom-right cell `(m - 1, n - 1)`.
* The path only ever moves **down** or **right**.
* The resulting parentheses string formed by the path is **valid**.

Return `true` _if there exists a **valid parentheses string path** in the grid._ Otherwise, return `false`.

**Example 1:**

![](https://assets.leetcode.com/uploads/2022/03/15/example1drawio.png)

**Input:** grid = [["(","(","("],[")","(",")"],["(","(",")"],["(","(",")"]]

**Output:** true

**Explanation:** The above diagram shows two possible paths that form valid parentheses strings.

The first path shown results in the valid parentheses string "()(())".

The second path shown results in the valid parentheses string "((()))".

Note that there may be other valid parentheses string paths.

**Example 2:**

![](https://assets.leetcode.com/uploads/2022/03/15/example2drawio.png)

**Input:** grid = [[")",")"],["(","("]]

**Output:** false

**Explanation:** The two possible paths form the parentheses strings "))(" and ")((". Since neither of them are valid parentheses strings, we return false.

**Constraints:**

* `m == grid.length`
* `n == grid[i].length`
* `1 <= m, n <= 100`
* `grid[i][j]` is either `'('` or `')'`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package g2201_2300.s2270_number_of_ways_to_split_array;

// #Medium #Array #Prefix_Sum #2022_06_15_Time_4_ms_(77.55%)_Space_91.9_MB_(18.27%)

public class Solution {
public int waysToSplitArray(int[] nums) {
long leftSum = 0;
long rightSum = 0;
for (int i : nums) {
rightSum += i;
}
int count = 0;
for (int i = 0; i < nums.length - 1; i++) {
rightSum -= nums[i];
leftSum += nums[i];
if (leftSum >= rightSum) {
count++;
}
}
return count;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
2270\. Number of Ways to Split Array

Medium

You are given a **0-indexed** integer array `nums` of length `n`.

`nums` contains a **valid split** at index `i` if the following are true:

* The sum of the first `i + 1` elements is **greater than or equal to** the sum of the last `n - i - 1` elements.
* There is **at least one** element to the right of `i`. That is, `0 <= i < n - 1`.

Return _the number of **valid splits** in_ `nums`.

**Example 1:**

**Input:** nums = [10,4,-8,7]

**Output:** 2

**Explanation:** There are three ways of splitting nums into two non-empty parts:

- Split nums at index 0. Then, the first part is [10], and its sum is 10. The second part is [4,-8,7], and its sum is 3. Since 10 >= 3, i = 0 is a valid split.

- Split nums at index 1. Then, the first part is [10,4], and its sum is 14. The second part is [-8,7], and its sum is -1. Since 14 >= -1, i = 1 is a valid split.

- Split nums at index 2. Then, the first part is [10,4,-8], and its sum is 6. The second part is [7], and its sum is 7. Since 6 < 7, i = 2 is not a valid split. Thus, the number of valid splits in nums is 2.

**Example 2:**

**Input:** nums = [2,3,1,0]

**Output:** 2

**Explanation:** There are two valid splits in nums:

- Split nums at index 1. Then, the first part is [2,3], and its sum is 5. The second part is [1,0], and its sum is 1. Since 5 >= 1, i = 1 is a valid split.

- Split nums at index 2. Then, the first part is [2,3,1], and its sum is 6. The second part is [0], and its sum is 0. Since 6 >= 0, i = 2 is a valid split.

**Constraints:**

* <code>2 <= nums.length <= 10<sup>5</sup></code>
* <code>-10<sup>5</sup> <= nums[i] <= 10<sup>5</sup></code>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package g2201_2300.s2266_count_number_of_texts;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.jupiter.api.Test;

class SolutionTest {
@Test
void countTexts() {
assertThat(new Solution().countTexts("22233"), equalTo(8));
}

@Test
void countTexts2() {
assertThat(
new Solution().countTexts("222222222222222222222222222222222222"),
equalTo(82876089));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package g2201_2300.s2267_check_if_there_is_a_valid_parentheses_string_path;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.jupiter.api.Test;

class SolutionTest {
@Test
void hasValidPath() {
assertThat(
new Solution()
.hasValidPath(
new char[][] {
{'(', '(', '('},
{')', '(', ')'},
{'(', '(', ')'},
{'(', '(', ')'}
}),
equalTo(true));
}

@Test
void hasValidPath2() {
assertThat(
new Solution().hasValidPath(new char[][] {{')', ')'}, {'(', '('}}), equalTo(false));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package g2201_2300.s2270_number_of_ways_to_split_array;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.jupiter.api.Test;

class SolutionTest {
@Test
void waysToSplitArray() {
assertThat(new Solution().waysToSplitArray(new int[] {10, 4, -8, 7}), equalTo(2));
}

@Test
void waysToSplitArray2() {
assertThat(new Solution().waysToSplitArray(new int[] {2, 3, 1, 0}), equalTo(2));
}
}