LeetCode Algorithm 0026 - 0030

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] [231,2311]. For the purpose of this problem, assume that your function returns 2 31 − 1 2^{31} - 1 2311 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;
        }
    };
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值