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
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package g1701_1800.s1753_maximum_score_from_removing_stones;

// #Medium #Math #Greedy #Heap_Priority_Queue #2022_04_30_Time_0_ms_(100.00%)_Space_41.5_MB_(70.96%)

import java.util.Arrays;

public class Solution {
public int maximumScore(int a, int b, int c) {
int[] nums = new int[] {a, b, c};
Arrays.sort(nums);
if (nums[0] + nums[1] < nums[2]) {
return nums[0] + nums[1];
} else {
return (nums[0] + nums[1] + nums[2]) / 2;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
1753\. Maximum Score From Removing Stones

Medium

You are playing a solitaire game with **three piles** of stones of sizes `a`, `b`, and `c` respectively. Each turn you choose two **different non-empty** piles, take one stone from each, and add `1` point to your score. The game stops when there are **fewer than two non-empty** piles (meaning there are no more available moves).

Given three integers `a`, `b`, and `c`, return _the_ **_maximum_** _**score** you can get._

**Example 1:**

**Input:** a = 2, b = 4, c = 6

**Output:** 6

**Explanation:** The starting state is (2, 4, 6). One optimal set of moves is:

- Take from 1st and 3rd piles, state is now (1, 4, 5)

- Take from 1st and 3rd piles, state is now (0, 4, 4)

- Take from 2nd and 3rd piles, state is now (0, 3, 3)

- Take from 2nd and 3rd piles, state is now (0, 2, 2)

- Take from 2nd and 3rd piles, state is now (0, 1, 1)

- Take from 2nd and 3rd piles, state is now (0, 0, 0)

There are fewer than two non-empty piles, so the game ends. Total: 6 points.

**Example 2:**

**Input:** a = 4, b = 4, c = 6

**Output:** 7

**Explanation:** The starting state is (4, 4, 6). One optimal set of moves is:

- Take from 1st and 2nd piles, state is now (3, 3, 6)

- Take from 1st and 3rd piles, state is now (2, 3, 5)

- Take from 1st and 3rd piles, state is now (1, 3, 4)

- Take from 1st and 3rd piles, state is now (0, 3, 3)

- Take from 2nd and 3rd piles, state is now (0, 2, 2)

- Take from 2nd and 3rd piles, state is now (0, 1, 1)

- Take from 2nd and 3rd piles, state is now (0, 0, 0)

There are fewer than two non-empty piles, so the game ends. Total: 7 points.

**Example 3:**

**Input:** a = 1, b = 8, c = 8

**Output:** 8

**Explanation:** One optimal set of moves is to take from the 2nd and 3rd piles for 8 turns until they are empty. After that, there are fewer than two non-empty piles, so the game ends.

**Constraints:**

* <code>1 <= a, b, c <= 10<sup>5</sup></code>
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package g1701_1800.s1754_largest_merge_of_two_strings;

// #Medium #String #Greedy #Two_Pointers #2022_04_30_Time_37_ms_(89.23%)_Space_53.8_MB_(53.08%)

public class Solution {
public String largestMerge(String word1, String word2) {
char[] a = word1.toCharArray();
char[] b = word2.toCharArray();
StringBuilder sb = new StringBuilder();
int i = 0;
int j = 0;
while (i < a.length && j < b.length) {
if (a[i] == b[j]) {
boolean first = go(a, i, b, j);
if (first) {
sb.append(a[i]);
i++;
} else {
sb.append(b[j]);
j++;
}
} else {
if (a[i] > b[j]) {
sb.append(a[i]);
i++;
} else {
sb.append(b[j]);
j++;
}
}
}

while (i < a.length) {
sb.append(a[i++]);
}
while (j < b.length) {
sb.append(b[j++]);
}

return sb.toString();
}

private boolean go(char[] a, int i, char[] b, int j) {
while (i < a.length && j < b.length && a[i] == b[j]) {
i++;
j++;
}
if (i == a.length) {
return false;
}
if (j == b.length) {
return true;
}
return a[i] > b[j];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
1754\. Largest Merge Of Two Strings

Medium

You are given two strings `word1` and `word2`. You want to construct a string `merge` in the following way: while either `word1` or `word2` are non-empty, choose **one** of the following options:

* If `word1` is non-empty, append the **first** character in `word1` to `merge` and delete it from `word1`.
* For example, if `word1 = "abc"` and `merge = "dv"`, then after choosing this operation, `word1 = "bc"` and `merge = "dva"`.
* If `word2` is non-empty, append the **first** character in `word2` to `merge` and delete it from `word2`.
* For example, if `word2 = "abc"` and `merge = ""`, then after choosing this operation, `word2 = "bc"` and `merge = "a"`.

Return _the lexicographically **largest**_ `merge` _you can construct_.

A string `a` is lexicographically larger than a string `b` (of the same length) if in the first position where `a` and `b` differ, `a` has a character strictly larger than the corresponding character in `b`. For example, `"abcd"` is lexicographically larger than `"abcc"` because the first position they differ is at the fourth character, and `d` is greater than `c`.

**Example 1:**

**Input:** word1 = "cabaa", word2 = "bcaaa"

**Output:** "cbcabaaaaa"

**Explanation:** One way to get the lexicographically largest merge is:

- Take from word1: merge = "c", word1 = "abaa", word2 = "bcaaa"

- Take from word2: merge = "cb", word1 = "abaa", word2 = "caaa"

- Take from word2: merge = "cbc", word1 = "abaa", word2 = "aaa"

- Take from word1: merge = "cbca", word1 = "baa", word2 = "aaa"

- Take from word1: merge = "cbcab", word1 = "aa", word2 = "aaa"

- Append the remaining 5 a's from word1 and word2 at the end of merge.

**Example 2:**

**Input:** word1 = "abcabc", word2 = "abdcaba"

**Output:** "abdcabcabcaba"

**Constraints:**

* `1 <= word1.length, word2.length <= 3000`
* `word1` and `word2` consist only of lowercase English letters.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package g1701_1800.s1755_closest_subsequence_sum;

// #Hard #Array #Dynamic_Programming #Two_Pointers #Bit_Manipulation #Bitmask
// #2022_04_30_Time_383_ms_(87.60%)_Space_65.5_MB_(78.51%)

import java.util.Arrays;

public class Solution {
private int idx;
private int sum;

public int minAbsDifference(int[] nums, int goal) {
int n = nums.length;

int nFirst = (int) Math.pow(2, (double) n / 2);
int nSecond = (int) Math.pow(2, n - n / 2);

int[] first = new int[nFirst];
int[] second = new int[nSecond];

helper(nums, first, 0, n / 2 - 1);
idx = sum = 0;
helper(nums, second, n / 2, n - 1);

Arrays.sort(first);
Arrays.sort(second);

int low = 0;
int high = nSecond - 1;

int ans = Integer.MAX_VALUE;
while (low < nFirst && high >= 0) {
int sum = first[low] + second[high];
ans = Math.min(ans, Math.abs(sum - goal));

if (ans == 0) {
break;
}

if (sum < goal) {
low++;
} else {
high--;
}
}

return ans;
}

private void helper(int[] nums, int[] arr, int start, int end) {
for (int i = start; i <= end; i++) {
sum += nums[i];
arr[idx++] = sum;
helper(nums, arr, i + 1, end);
sum -= nums[i];
}
}
}
39 changes: 39 additions & 0 deletions src/main/java/g1701_1800/s1755_closest_subsequence_sum/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
1755\. Closest Subsequence Sum

Hard

You are given an integer array `nums` and an integer `goal`.

You want to choose a subsequence of `nums` such that the sum of its elements is the closest possible to `goal`. That is, if the sum of the subsequence's elements is `sum`, then you want to **minimize the absolute difference** `abs(sum - goal)`.

Return _the **minimum** possible value of_ `abs(sum - goal)`.

Note that a subsequence of an array is an array formed by removing some elements **(possibly all or none)** of the original array.

**Example 1:**

**Input:** nums = [5,-7,3,5], goal = 6

**Output:** 0

**Explanation:** Choose the whole array as a subsequence, with a sum of 6. This is equal to the goal, so the absolute difference is 0.

**Example 2:**

**Input:** nums = [7,-9,15,-2], goal = -5

**Output:** 1

**Explanation:** Choose the subsequence [7,-9,-2], with a sum of -4. The absolute difference is abs(-4 - (-5)) = abs(1) = 1, which is the minimum.

**Example 3:**

**Input:** nums = [1,2,3], goal = -7

**Output:** 7

**Constraints:**

* `1 <= nums.length <= 40`
* <code>-10<sup>7</sup> <= nums[i] <= 10<sup>7</sup></code>
* <code>-10<sup>9</sup> <= goal <= 10<sup>9</sup></code>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package g1701_1800.s1758_minimum_changes_to_make_alternating_binary_string;

// #Easy #String #2022_04_30_Time_10_ms_(9.93%)_Space_42.9_MB_(56.74%)

public class Solution {
public int minOperations(String s) {
int ops1 = 0;
for (int i = 0; i < s.length(); i++) {
if (i % 2 == 0) {
if (s.charAt(i) != '0') {
ops1++;
}
} else {
if (s.charAt(i) != '1') {
ops1++;
}
}
}

int ops2 = 0;
for (int i = 0; i < s.length(); i++) {
if (i % 2 == 0) {
if (s.charAt(i) != '1') {
ops2++;
}
} else {
if (s.charAt(i) != '0') {
ops2++;
}
}
}
return Math.min(ops1, ops2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
1758\. Minimum Changes To Make Alternating Binary String

Easy

You are given a string `s` consisting only of the characters `'0'` and `'1'`. In one operation, you can change any `'0'` to `'1'` or vice versa.

The string is called alternating if no two adjacent characters are equal. For example, the string `"010"` is alternating, while the string `"0100"` is not.

Return _the **minimum** number of operations needed to make_ `s` _alternating_.

**Example 1:**

**Input:** s = "0100"

**Output:** 1

**Explanation:** If you change the last character to '1', s will be "0101", which is alternating.

**Example 2:**

**Input:** s = "10"

**Output:** 0

**Explanation:** s is already alternating.

**Example 3:**

**Input:** s = "1111"

**Output:** 2

**Explanation:** You need two operations to reach "0101" or "1010".

**Constraints:**

* <code>1 <= s.length <= 10<sup>4</sup></code>
* `s[i]` is either `'0'` or `'1'`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package g1701_1800.s1759_count_number_of_homogenous_substrings;

// #Medium #String #Math #2022_04_30_Time_19_ms_(42.40%)_Space_51.3_MB_(28.80%)

public class Solution {
public int countHomogenous(String s) {
int total = 0;
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (i > 0 && s.charAt(i) == s.charAt(i - 1)) {
count++;
} else {
count = 1;
}
total = (total + count) % 1000000007;
}
return total;
}
}
Loading