Two Pointers

Sujinยท2022๋…„ 12์›” 1์ผ
0

LeetCode

๋ชฉ๋ก ๋ณด๊ธฐ
2/24
post-thumbnail

๐Ÿ’ก Valid Palindrome

A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.

Given a string s, return true if it is a palindrome, or false otherwise.

Example 1:

Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.

Example 2:

Input: s = "race a car"
Output: false
Explanation: "raceacar" is not a palindrome.

Example 3:

Input: s = " "
Output: true
Explanation: s is an empty string "" after removing non-alphanumeric characters.
Since an empty string reads the same forward and backward, it is a palindrome.

Constraints:

  • 1 <= s.length <= 2 * 105
  • s consists only of printable ASCII characters.

Solution

class Solution {
public:
    bool isPalindrome(string s) {
        int i = 0;
        int j = s.size() - 1;
        
        while (i < j) {
            while (!isalnum(s[i]) && i < j) {
                i++;
            }
            while (!isalnum(s[j]) && i < j) {
                j--;
            }

            if (tolower(s[i]) != tolower(s[j])) {
                return false;
            }
            i++;
            j--;
        }
        
        return true;
    }
};

๐Ÿ’ก 3Sum

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

Notice that the solution set must not contain duplicate triplets.

Example 1:

Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Explanation: 
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0.
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0.
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0.
The distinct triplets are [-1,0,1] and [-1,-1,2].
Notice that the order of the output and the order of the triplets does not matter.

Example 2:

Input: nums = [0,1,1]
Output: []
Explanation: The only possible triplet does not sum up to 0.

Example 3:

Input: nums = [0,0,0]
Output: [[0,0,0]]
Explanation: The only possible triplet sums up to 0.

Constraints:

  • 3 <= nums.length <= 3000
  • 105 <= nums[i] <= 105

Solution

  1. edgecase: nums verctor ๊ฐ€ 3๊ฐœ ๋ฏธ๋งŒ์˜ ์ˆซ์ž๋ฅผ ๊ฐ€์ง€๋ฉด โ†’ return []
  2. sort nums vector, ๊ทธ๋ž˜์„œ ์ž‘์€ ๊ฐ’๋“ค์ด ๋ชจ๋‘ ์™ผ์ชฝ์—, ํฐ ๊ฐ’๋“ค์ด ๋ชจ๋‘ ์˜ค๋ฅธ์ชฝ์— ์˜ค๋„๋ก ํ•œ๋‹ค
  3. ์ด๋•Œ ์ฒซ๋ฒˆ์จฐ ๊ฐ’์ด positive number๋ฉด ํ•ด๋Š” ์—†์œผ๋ฏ€๋กœ []๋ฅผ return
  4. ์ค‘๋ณต ๊ฐ’์€ ๋„˜์–ด๊ฐ„๋‹ค (์–ด์ฐจํ”ผ ๊ฐ™์€ result๋ฅผ ๋งŒ๋“ค์–ด ๋ƒ„)
  5. ํ˜„์žฌ ๋ณด๊ณ ์žˆ๋Š” ์ˆซ์ž์—์„œ ๋ฐ”๋กœ ๋‹ค์Œ๊ฐ’(j)๊ณผ vector์˜ ๋งˆ์ง€๋ง‰ ๊ฐ’(k)์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๋”ํ•ด๋ณด๋ฉด์„œ ํ•ด๋ฅผ ์ฐพ๋Š”๋‹ค
    • vector์„ sort ํ•ด๋†จ๊ธฐ ๋•Œ๋ฌธ์—, ์ด์ „๊ฐ’์€ ๋ณด์ง€ ์•Š์•„๋„ ๋œ๋‹ค (0์—์„œ ๋ฉ€์–ด์ง„๋‹ค)
    • ์„ธ์ˆซ์ž๋ฅผ ๋”ํ•˜๋ฉด์„œ 0๋ณด๋‹ค ์ž‘์œผ๋ฉด: ๊ฐ’์ด ์ปค์ง€๋„๋ก j๋ฅผ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์˜ฎ๊ธด๋‹ค
    • ์„ธ์ˆซ์ž๋ฅผ ๋”ํ•˜๋ฉด์„œ 0๋ณด๋‹ค ํฌ๋ฉด: ์ž‘์•„์ง€๋„๋ก k๋ฅผ ์™ผ์ชฝ์œผ๋กœ ์˜ฎ๊ธด๋‹ค
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;
        int n = nums.size();

        // 3๊ฐœ ๋ฏธ๋งŒ์˜ elements
        if (n < 3) return result;

        // sort
        sort(nums.begin(), nums.end());

        // ์ฒซ๋ฒˆ์จฐ ๊ฐ’์ด positive number๋ฉด no solution
        if (nums[0] > 0) return result;

        for (int i = 0; i < n - 2; i++) { //O(n)
            // consume all the duplicates
            if (i > 0 && nums[i] == nums[i-1]) continue;

            int j = i + 1;
            int k = n - 1;

            while (j < k) { //O(n)
                int sum = nums[i] + nums[j] + nums[k];

                if (sum < 0) {
                    // ๊ฐ’์ด ์ปค์ง€๋„๋ก j๋ฅผ ์˜ค๋ฅธ์ชฝ์œผ๋กœ
                    j++;
                } else if (sum > 0) {
                    // ๊ฐ’์ด ์ž‘์•„์ง€๋„๋ก k๋ฅผ ์™ผ์ชฝ์œผ๋กœ
                    k--;
                } else {
                    result.push_back({nums[i], nums[j], nums[k]});

                    while (j < k && nums[j] == nums[j+1]) {
                        // consume all the duplicates
                        j++;
                    }
                    j++;

                    while (j < k && nums[k-1] == nums[k]) {
                        // consume all the duplicates
                        k--;
                    }
                    k--;
                }
            }
        } //O(n^2)

        return result;
    }
};

๐Ÿ’ก Container With Most Water

You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]).

Find two lines that together with the x-axis form a container, such that the container contains the most water.

Return the maximum amount of water a container can store.

Notice that you may not slant the container.

Example 1:

Input: height = [1,8,6,2,5,4,8,3,7]
Output: 49
Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.

Example 2:

Input: height = [1,1]
Output: 1

Constraints:

  • n == height.length
  • 2 <= n <= 105
  • 0 <= height[i] <= 104

Solution

Greedy Algorithm

class Solution {
public:
    int maxArea(vector<int>& height) {
        int i = 0;
        int j = height.size() - 1;

        int result = 0;

        while (i < j) {
            int volume = (j - i) * (min(height[i], height[j]));
            result = max(volume, result);

            // give up the shorter one and try the next one
            if (height[i] <= height[j]) {
                i++;
            } else {
                j--;
            }
        }

        return result;
    }
};
profile
๋ฉ‹์ฐ ๋‚˜ ,,(๊ฐ€ ๋˜๊ณ ํ”ˆ)

0๊ฐœ์˜ ๋Œ“๊ธ€