LeetCode Algorithm 0026 - 0030

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/darkrabbit/article/details/82927098

LeetCode Algorithm 0026 - 0030



0026 - Remove Duplicates from Sorted Array (Easy)

Problem Link: https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/

Description

Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length.

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

Example 1:

Given nums = [1,1,2],

Your function should return length = 2, 
with the first two elements of nums being 1 and 2 respectively.

It doesn't matter what you leave beyond the returned length.

Example 2:

Given nums = [0,0,1,1,1,2,2,3,3,4],

Your function should return length = 5, with the first five 
elements of nums being modified to 0, 1, 2, 3, and 4 respectively.

It doesn't matter what values are set beyond the returned length.

Clarification:

Confused why the returned value is an integer but your answer is an array?

Note that the input array is passed in by reference , which means modification to the input array will be known to the caller as well.

Internally you can think of this:

// nums is passed in by reference. (i.e., without making a copy)
int len = removeDuplicates(nums);

// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

Solution C++

#pragma once

#include "pch.h"

// Problem: https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/

namespace P26RemoveDuplicatesFromSortedArray
{
    class Solution
    {
        public:
        int removeDuplicates(vector<int>& nums)
        {
            if (nums.empty())
            {
                return 0;
            }

            unordered_set<int> numSet;
            int length = 0;
            for (vector<int>::iterator it = nums.begin(); it != nums.end();)
            {
                if (numSet.find(*it) == numSet.end())
                {
                    numSet.insert(*it);
                    length++;
                    it++;
                }
                else
                {
                    nums.erase(it);
                }
            }

            return length;
        }
    };
}


0027 - Remove Element (Easy)

Problem Link: https://leetcode.com/problems/remove-element/description/

Description

Given an array nums and a value val, remove all instances of that value in-place and return the new length.

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

The order of elements can be changed. It doesn’t matter what you leave beyond the new length.

Example 1:

Given nums = [3,2,2,3], val = 3,

Your function should return length = 2, 
with the first two elements of nums being 2.

It doesn't matter what you leave beyond the returned length.

Example 2:

Given nums = [0,1,2,2,3,0,4,2], val = 2,

Your function should return length = 5, 
with the first five elements of nums containing 0, 1, 3, 0, and 4.

Note that the order of those five elements can be arbitrary.

It doesn't matter what values are set beyond the returned length.

Clarification:

Confused why the returned value is an integer but your answer is an array?

Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.

Internally you can think of this:

// nums is passed in by reference. (i.e., without making a copy)
int len = removeElement(nums, val);

// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

Solution C++

#pragma once

#include "pch.h"

// Problem: https://leetcode.com/problems/remove-element/description/

namespace P27RemoveElement
{
    class Solution
    {
        public:
        int removeElement(vector<int>& nums, int val)
        {
            if (nums.empty())
            {
                return 0;
            }

            int length = 0;
            for (vector<int>::iterator it = nums.begin(); it != nums.end();)
            {
                if (*it == val)
                {
                    nums.erase(it);
                }
                else
                {
                    it++;
                    length++;
                }
            }

            return length;
        }
    };
}


0028 - Implement strStr() (Easy)

Problem Link: https://leetcode.com/problems/implement-strstr/description/

Description

Implement strStr().

Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

Example 1:

Input: haystack = "hello", needle = "ll"
Output: 2

Example 2:

Input: haystack = "aaaaa", needle = "bba"
Output: -1

Clarification:

What should we return when needle is an empty string? This is a great question to ask during an interview.

For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C’s strStr() and Java’s indexOf().

Solution C++

#pragma once

#include "pch.h"

// Problem: https://leetcode.com/problems/implement-strstr/description/

namespace P28Implement_strStr
{
    class Solution
    {
        public:
        int strStr(string haystack, string needle)
        {
            if (needle.empty())
            {
                return 0;
            }

            if (haystack.empty() || haystack.size() < needle.size())
            {
                return -1;
            }

            int needleSize = needle.size();

            for (size_t i = 0; i <= haystack.size() - needleSize; i++)
            {
                if (haystack[0] == needle[0] && haystack.substr(i, needleSize) == needle)
                {
                    return i;
                }
            }

            return -1;
        }
    };
}


0029 - Divide Two Integers (Medium)

Problem Link: https://leetcode.com/problems/divide-two-integers/description/

Description

Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.

Return the quotient after dividing dividend by divisor.

The integer division should truncate toward zero.

Example 1:

Input: dividend = 10, divisor = 3
Output: 3

Example 2:

Input: dividend = 7, divisor = -3
Output: -2

Note:

  • Both dividend and divisor will be 32-bit signed integers.
  • The divisor will never be 0.
  • Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [ 2 31 , 2 31 1 ] [-2^{31}, 2^{31} - 1] . For the purpose of this problem, assume that your function returns 2 31 1 2^{31} - 1 when the division result overflows.

Solution C++

#pragma once

#include "pch.h"

// Problem: https://leetcode.com/problems/divide-two-integers/description/

namespace P29DivideTwoIntegers
{
    class Solution
    {
        public:
        int divide(int dividend, int divisor)
        {
            // 题目要求,只能使用`有符号32位整数`,
            // 所以不能使用 unsigned, long long 和 size_t 等等类型,只能使用类型 int32_t 。
            // 要注意 C++ 在不同环境中 int 的取值范围,这里假设为 负的2的31次方 到 2的31次方减1 。
            // 还要求不能使用 *, / 和 % 。

            // error,题目已经明确输入的 divisor 不会为 0,但还是判断一下
            if (divisor == 0)
            {
                return -1;
            }

            if (dividend == 0
                || (dividend > 0 && dividend < divisor)
                || (dividend < 0 && dividend > divisor))
            {
                return 0;
            }

            if (dividend == divisor)
            {
                return 1;
            }

            if (dividend == -divisor)
            {
                return -1;
            }

            int sign1, sign2, abs1, neg1, abs2, neg2;

            if (dividend > 0)
            {
                sign1 = 1;
                abs1 = dividend;
                neg1 = -dividend;
            }
            else
            {
                sign1 = -1;
                abs1 = -dividend;
                neg1 = dividend;
            }

            if (divisor > 0)
            {
                sign2 = 1;
                abs2 = divisor;
                neg2 = -divisor;
            }
            else
            {
                sign2 = -1;
                abs2 = -divisor;
                neg2 = divisor;
            }

            // INT_MIN = 1000 0000 0000 0000 0000 0000 0000 0000
            // INT_MAX = 0111 1111 1111 1111 1111 1111 1111 1111
            const int maxth = 1 << 30; // 0100 0000 0000 0000 0000 0000 0000 0000
            int result = 0;

            // 二进制
            // 乘法举例:10 * 3
            //  1010 * 0011 = 1010 * (0010 + 0001) 
            //              = 1010 << 1 + 1010 << 0 (0010 = 1 << 1, 0001 = 1 << 0)
            //              = 0001 0100 + 1010 = 0001 1110 = 30
            // 除法举例:10 / 3
            //  1010 / 0011 = 1010 / (0010 + 0001)
            //
            //  按乘法反推:1010 >= (0011 << n1) + (0011 << n2)
            //      1010 >= (0011 << n1) => n1 最大能为 1
            //      
            //      1010 - (0011 << n1) >= (0011 << n2) => (n1 = 1)
            //      1010 - 110 = 100    >= (0011 << n2) => n2 最大能为 0
            //
            //      result = (1 << n1) + (1 << n2) = 0010 + 0001 = 0011 = 3
            while (neg1 <= neg2)
            {
                int d, quotient;
                for (d = abs2, quotient = 1;; d <<= 1, quotient <<= 1)
                {
                    if ((d & maxth) != 0 || -(d << 1) < neg1)
                    {
                        break;
                    }
                }

                neg1 += d;
                result -= quotient;

                if (result == INT_MIN) // INT_MIN / -1 = INT_MAX + 1 ,强制让它等于 INT_MAX
                {
                    if (sign1 == sign2)
                    {
                        result += 1;
                    }
                    break;
                }
            }

            return sign1 == sign2 ? -result : result;
        }
    };
}


0030 - Substring with Concatenation of All Words (Hard)

Problem Link: https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/

Description

You are given a string, s , and a list of words, words , that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

Example 1:

Input:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
Output: [0,9]
Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively.
The output order does not matter, returning [9,0] is fine too.

Example 2:

Input:
  s = "wordgoodstudentgoodword",
  words = ["word","student"]
Output: []

Solution C++

#pragma once

#include "pch.h"

// Problem: https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/

namespace P30SubstringWithConcatenationOfAllWords
{
    class Solution
    {
        public:
        vector<int> findSubstring(string s, vector<string>& words)
        {
            // 没有字符串或单词
            if (s.empty() || words.empty())
            {
                return vector<int>();
            }

            // 单词计数
            unordered_map<string, int> countMap;
            for (size_t i = 0; i < words.size(); i++)
            {
                if (words[i].size() == 0)
                {
                    continue;
                }
                countMap[words[i]] += 1;
            }

            // 开始计算
            int lenStr = s.size(); // 字符串长度
            int numWords = words.size(); // 单词数量
            int lenWord = words[0].size(); // 单词长度

            vector<int> result;
            for (int i = 0; i <= lenStr - numWords * lenWord; i++)
            {
                unordered_map<string, int> useCountMap;
                int j = 0;
                for (j; j < numWords; j++)
                {
                    string word = s.substr(i + j * lenWord, lenWord); // 分割字符串
                    if (countMap.find(word) != countMap.end())
                    {
                        useCountMap[word] += 1;
                        if (useCountMap[word] > countMap[word])
                        {
                            break;
                        }
                    }
                    else // 不存在
                    {
                        break;
                    }
                }

                if (j == numWords)
                {
                    result.push_back(i);
                }
            }

            return result;
        }
    };
}


猜你喜欢

转载自blog.csdn.net/darkrabbit/article/details/82927098