Leetcode 1717. Maximum Score From Removing Substrings

2024/07/12 的每日一題!

題目描述

You are given a string s and two integers x and y. You can perform two types of operations any number of times.

  • Remove substring "ab" and gain x points.
    • For example, when removing "ab" from "cabxbae" it becomes "cxbae".
  • Remove substring "ba" and gain y points.
    • For example, when removing "ba" from "cabxbae" it becomes "cabxe". Return the maximum points you can gain after applying the above operations on s.

範例

Example 1:

Input: s = "cdbcbbaaabab", x = 4, y = 5
Output: 19
Explanation:
- Remove the "ba" underlined in "cdbcbbaaabab". Now, s = "cdbcbbaaab" and 5 points are added to the score.
- Remove the "ab" underlined in "cdbcbbaaab". Now, s = "cdbcbbaa" and 4 points are added to the score.
- Remove the "ba" underlined in "cdbcbbaa". Now, s = "cdbcba" and 5 points are added to the score.
- Remove the "ba" underlined in "cdbcba". Now, s = "cdbc" and 5 points are added to the score.
Total score = 5 + 4 + 5 + 5 = 19.

Example 2:

Input: s = "aabbaaxybbaabb", x = 5, y = 4
Output: 20

Constraints:

  • 1 <= s.length <= 10^5
  • 1 <= x, y <= 10^4
  • s consists of lowercase English letters.

解法

方法:寫一個叫做 remove 的方法,該方法利用 stack 消除所有 removestr,並將每個 removestr 作為 val 值加總在一起並回傳。 針對題目字串,如果x較大,我們就先處理 ab,如 y 較大,處理 ba。

func maximumGain(s string, x int, y int) int {
    
    remove := func(str string, removestr string, val int) int {
        count := 0
        stack := make([]byte, 0)

        for i:=0; i<len(str); i++ {
            stack = append(stack, str[i])

            l := len(stack)
            if l >= 2 && stack[l-1]==removestr[1] && stack[l-2]==removestr[0] {
                count += val
                stack = stack[:l-2]
            }
        }

        s = string(stack)

        return count
    }

    if x > y { 
        return remove(s, "ab", x) + remove(s, "ba", y) 
    } else {
        return remove(s, "ba", y) + remove(s, "ab", x)
    }
    

    return 0
}

Time complexity : O(n) Space complexity : O(n)

Leetcode 27. Remove Element

Leetcode Top Interview 150 的其中一題

題目描述

Given an integer array nums and an integer val, remove all occurrences of val in nums in-place. The order of the elements may be changed. Then return the number of elements in nums which are not equal to val.

Consider the number of elements in nums which are not equal to val be k, to get accepted, you need to do the following things:

Change the array nums such that the first k elements of nums contain the elements which are not equal to val. The remaining elements of nums are not important as well as the size of nums. Return k.

Custom Judge:

int[] nums = [...]; // Input array
int val = ...; // Value to remove
int[] expectedNums = [...]; // The expected answer with correct length.
                            // It is sorted with no values equaling val.

int k = removeElement(nums, val); // Calls your implementation

assert k == expectedNums.length;
sort(nums, 0, k); // Sort the first k elements of nums
for (int i = 0; i < actualLength; i++) {
    assert nums[i] == expectedNums[i];
}

If all assertions pass, then your solution will be accepted.

範例

Example 1:

Input: nums = [3,2,2,3], val = 3
Output: 2, nums = [2,2,_,_]
Explanation: Your function should return k = 2, with the first two elements of nums being 2.
It does not matter what you leave beyond the returned k (hence they are underscores).

Example 2:

Input: nums = [0,1,2,2,3,0,4,2], val = 2
Output: 5, nums = [0,1,4,0,3,_,_,_]
Explanation: Your function should return k = 5, with the first five elements of nums containing 0, 0, 1, 3, and 4.
Note that the five elements can be returned in any order.
It does not matter what you leave beyond the returned k (hence they are underscores).

Constraints:

  • 0 <= nums.length <= 100
  • 0 <= nums[i] <= 50
  • 0 <= val <= 100

解法

方法:檢查每個數字現在是否等於 val,是的話改成 100001,這樣排序後就會在最後面,不在列入檢查的陣列前面

func removeElement(nums []int, val int) int {
    count := 0

    for i:=0; i<len(nums); i++ {
        if nums[i] == val {
            nums[i] = 101
            count++
        }
    }

    sort.Ints(nums)

    return len(nums)-count
}

Time complexity : O(nlogn)

Leetcode 80. Remove Duplicates from Sorted Array II (Medium)

Leetcode Top Interview 150 的其中一題

題目描述

Given an integer array nums sorted in non-decreasing order, remove some duplicates in-place such that each unique element appears at most twice. The relative order of the elements should be kept the same.

Since it is impossible to change the length of the array in some languages, you must instead have the result be placed in the first part of the array nums. More formally, if there are k elements after removing the duplicates, then the first k elements of nums should hold the final result. It does not matter what you leave beyond the first k elements.

Return k after placing the final result in the first k slots of nums.

Do not allocate extra space for another array. You must do this by modifying the input array in-place with O(1) extra memory.

Custom Judge:

The judge will test your solution with the following code:

int[] nums = [...]; // Input array
int[] expectedNums = [...]; // The expected answer with correct length

int k = removeDuplicates(nums); // Calls your implementation

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
}

If all assertions pass, then your solution will be accepted.

範例

Example 1:

Input: nums = [1,1,1,2,2,3]
Output: 5, nums = [1,1,2,2,3,_]
Explanation: Your function should return k = 5, with the first five elements of nums being 1, 1, 2, 2 and 3 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).

Example 2:

Input: nums = [0,0,1,1,1,1,2,3,3]
Output: 7, nums = [0,0,1,1,2,3,3,_,_]
Explanation: Your function should return k = 7, with the first seven elements of nums being 0, 0, 1, 1, 2, 3 and 3 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).

Constraints:

  • 1 <= nums.length <= 3 * 104
  • -104 <= nums[i] <= 104
  • nums is sorted in non-decreasing order.

解法

這一題和上一題 26. 類似,只是我們要讓每個數字只能出現兩次,要在原本的陣列內實作且只能有 O(1) 的 extra memory。 方法:檢查每個數字現在是否是出現第三次以上,是的話改成 100001,這樣排序後就會在最後面,不在列入檢查的陣列前面

func removeDuplicates(nums []int) int {
    count := 1
    now := nums[0]
    ans := len(nums)

    for i:=1; i<len(nums); i++ {
        if nums[i] == now {
            count++
        } else {
            count = 1
            now= nums[i]
        }

        if count > 2 {
            nums[i] = 100001
            ans--
        }
    }

    sort.Ints(nums)

    return ans
}

Leetcode 26. Remove Duplicates from Sorted Array (Easy)

Leetcode Top Interview 150 的其中一題

題目描述

Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. The relative order of the elements should be kept the same. Then return the number of unique elements in nums.

Consider the number of unique elements of nums to be k, to get accepted, you need to do the following things:

  • Change the array nums such that the first k elements of nums contain the unique elements in the order they were present in nums initially. The remaining elements of nums are not important as well as the size of nums.
  • Return k.

Custom Judge:

The judge will test your solution with the following code:

int[] nums = [...]; // Input array
int[] expectedNums = [...]; // The expected answer with correct length

int k = removeDuplicates(nums); // Calls your implementation

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
}
If all assertions pass, then your solution will be accepted.

範例

Example 1:

Input: nums = [1,1,2]
Output: 2, nums = [1,2,_]
Explanation: Your function should return k = 2, with the first two elements of nums being 1 and 2 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).

Example 2:

Input: nums = [0,0,1,1,1,2,2,3,3,4]
Output: 5, nums = [0,1,2,3,4,_,_,_,_,_]
Explanation: Your function should return k = 5, with the first five elements of nums being 0, 1, 2, 3, and 4 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).

Constraints

  • 1 <= nums.length <= 3 * 10^4
  • -100 <= nums[i] <= 100
  • nums is sorted in non-decreasing order.

解法

解法一

解題思路:

把出現第二次以上的數字更改為 101 ,並將 duplicate +1 。因為nums[i]最大為 100,101一定會在排序時被排到最後面 ,所以前 len(nums) - duplicate 個數字一定都只出現一次

func removeDuplicates(nums []int) int {
    prev := nums[0]
    duplicate := 0

    for i:=1; i<len(nums); i++ {
        if nums[i] == prev {
            nums[i] =101
            duplicate++
        } else {
            prev = nums[i]
        }
    }

    sort.Ints(nums)

    return len(nums) - duplicate
}

Leetcode 88. Merge Sorted Array (Easy)

Leetcode Top Interview 150 的其中一題

題目描述

You are given two integer arrays nums1 and nums2, sorted in non-decreasing order, and two integers m and n, representing the number of elements in nums1 and nums2 respectively. Merge nums1 and nums2 into a single array sorted in non-decreasing order. The final sorted array should not be returned by the function, but instead be stored inside the array nums1. To accommodate this, nums1 has a length of m + n, where the first m elements denote the elements that should be merged, and the last n elements are set to 0 and should be ignored.nums2 has a length of n.

範例

Example 1:

Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
Output: [1,2,2,3,5,6]
Explanation: The arrays we are merging are [1,2,3] and [2,5,6].
The result of the merge is [1,2,2,3,5,6] with the underlined elements coming from nums1.

Example 2:

Input: nums1 = [1], m = 1, nums2 = [], n = 0
Output: [1]
Explanation: The arrays we are merging are [1] and [].
The result of the merge is [1].

Example 3:

Input: nums1 = [0], m = 0, nums2 = [1], n = 1
Output: [1]
Explanation: The arrays we are merging are [] and [1].
The result of the merge is [1].
Note that because m = 0, there are no elements in nums1. The 0 is only there to ensure the merge result can fit in nums1.

Constraints

  • nums1.length == m + n
  • nums2.length == n
  • 0 <= m, n <= 200
  • 1 <= m + n <= 200
  • -10^9 <= nums1[i], nums2[j] <= 10^9

Follow up: Can you come up with an algorithm that runs in O(m + n) time?

解法

解法一

第一個解法有點簡單暴力,把 nums2 的值放到nums1 後段後,直接做排序

func merge(nums1 []int, m int, nums2 []int, n int)  {
    for j := m; j < len(nums1); j++ {
        nums1[j] = nums2[j-m]
    }

    sort.Ints(nums1)
}

解法二

這個解法很巧妙!因為 nums1 最後 n 格是空的,所以我們可以從 nums1 有數值的地方的尾巴(nums1最大的值) 和 nums2 最大的值開始比較,把比較大的填到 nums1 的最後,以此類推,從大的開始填

func merge(nums1 []int, m int, nums2 []int, n int)  {
    k := m+n-1 //最後一格
    i := m-1
    j := n-1

    for j>=0 {
        if i >= 0 && (nums1[i] > nums2[j]) {
            nums1[k] = nums1[i]
            i--
        } else {
            nums1[k] = nums2[j]
            j--
        }
        k--
    }
}