Task03-using C++

Insert picture description here

011 The container with the most water

Insert picture description here
LeetCode link
https://leetcode-cn.com/problems/container-with-most-water/

Ideas:

Use the double pointer left and right to solve the problem violently, because the volume=(right-left)*min(height[left], height[right]). Therefore, we can use the double pointer to move the short board at both ends of the array each time. Compare the size of each area and find the largest container step by step.

C++ code:

class Solution
{
    
    
public:
    int maxArea(vector<int> &height)
    {
    
    
        int left = 0;
        int right = height.size() - 1;
        int Area = 0;
        int MaxArea = 0;
        while (left != right)
        {
    
    
            int H = min(height[left], height[right]);
            Area = H * (right - left);
            if(MaxArea<Area)
                MaxArea = Area;
            if(height[left]<=height[right])
                left++;
            else 
                right--;
        }
        return MaxArea;
    }
};

Insert picture description here

014 Longest common prefix

Insert picture description here
LeetCode:https://leetcode-cn.com/problems/longest-common-prefix/

Ideas:

The first is the brute force method, which directly compares each bit of the first string with the following strings. The time complexity is a bit high, but it will not TLE.

C++ code:

//初始代码
class Solution
{
    
    
public:
    string longestCommonPrefix(vector<string> &strs)
    {
    
    
        string result = "";
        if(!strs.size())
            return result;
        for (int j=0;j<strs[0].size();j++){
    
    //第j位字符
       		 for (int i=1;i<strs.size();i++){
    
    //第i个字符串
            		if (strs[i][j]!=strs[0][j])
                		return result;
        }
        result += strs[0][j];
    }
    return result;
    }
};

Insert picture description here

The second is a little optimization. I sorted it first. If the shortest string and the longest string (in fact, it’s not the longest and no problem) do not have the same prefix, then the entire string array will not . If so, store it in the result, and then look for the number of substrings in strs. If the number is equal to the number of strings in strs, it means that the result is the same prefix. As for why it is sorted, not the first One and the second. Take a look at the following case.Insert picture description here

C++ code:

class Solution
{
    
    
public:
    string longestCommonPrefix(vector<string> &strs)
    {
    
    
        string result = "";
        if (strs.size() < 1)
            return result;
        sort(strs.begin(), strs.end());
        string s1 = *strs.begin(), s2 = *(strs.end() - 1);
        int i = 0;
        while (i < s1.length())
        {
    
    
            if (s1[i] != s2[i])
                break;
            result.push_back(s1[i]);
            i++;
        }
        if (i == 0)
            return "";
        int flag = 0;
        for (int j = 0; j < strs.size(); j++)
        {
    
    
            if (strs[j].find(result) != -1)
                flag++;
        }
        if (flag != strs.size())
            return "";
        return result;
    }
};

Insert picture description here

015 Sansanowa

Insert picture description here
LeetCode link : https://leetcode-cn.com/problems/3sum/

First, let’s put a TTL violent solution, triple loop nesting + set container de-duplication, complexity O(n^3)
Insert picture description here

C++ code:

class Solution
{
    
    
public:
    vector<vector<int>> threeSum(vector<int> &nums)
    {
    
    
        set<vector<int>> result;
        for (int i = 0; i < nums.size(); i++)
        {
    
    
            for (int j = i+1; j < nums.size(); j++)
            {
    
    
                for (int k = j+1; k < nums.size(); k++)
                {
    
    
                    if (nums[i] + nums[j] + nums[k] == 0)
                    {
    
    
                        vector<int> temp;
                        temp.push_back(nums[i]);
                        temp.push_back(nums[j]);
                        temp.push_back(nums[k]);
                        sort(temp.begin(),temp.end());//排序是为了去重
                        result.insert(temp);
                    }
                }
            }
        }
        return vector<vector<int>>(result.begin(),result.end());
    }
};

Idea 1: First sort the array, and then treat each element as the middle element, and use the half search method to set the left and right flags. If the sum of three numbers is greater than 0, left --, if the sum of three numbers is less than 0, right ++, use the set collection to remove duplicates when assigning values.
But this method is particularly prone to timeout, and the complexity is too high.
Insert picture description here

C++ code:

class Solution {
    
    
public:
	vector<vector<int>> threeSum(vector<int>& nums)
	{
    
    
		set<vector<int>> result;
		if (nums.size() < 3)
		{
    
    
			return{
    
    };
		}

		sort(nums.begin(), nums.end());
		int left;
		int right;
		int sum;
		for (int i = 1; i < nums.size(); i++)
		{
    
    
			left = i - 1;
			right = i + 1;
			while (left >= 0 && right < nums.size())
			{
    
    
				sum = nums[i] + nums[left] + nums[right];
				if (0 == sum)
				{
    
    
					vector<int> three;
					three.push_back(nums[i]);
					three.push_back(nums[left]);
					three.push_back(nums[right]);
					result.insert(three);
					int last_left = nums[left];
					int last_right = nums[right];
					left--;
					right++;
					while (left >= 0 && last_left == nums[left])
					{
    
    
						left--;
					}
					while (right < nums.size() && last_right == nums[right])
					{
    
    
						right++;
					}
				}
				else if(sum < 0)
				{
    
    
					int last_right = nums[right];
					right++;
					while (right < nums.size() && last_right == nums[right])
					{
    
    
						right++;
					}
				}
				else
				{
    
    
					int last_left = nums[left];
					left--;
					while (left >= 0 && last_left == nums[left])
					{
    
    
						left--;
					}
				}
			}
		}

		return vector<vector<int>>(result.begin(), result.end());
	}
};

Idea 2: Or let the current element i as the smallest element, left=i+1, right=nums.size()-1, if the result is greater than 0, right–, if the result is less than 0, left++; this method does not need to set to remove duplicates .

C++ code:

There is a little problem with the code, that is, this set of data
Insert picture description here

class Solution
{
    
    
public:
    vector<vector<int>> threeSum(vector<int> &nums)
    {
    
    
        set<vector<int>> result;
        sort(nums.begin(), nums.end());
        for (int i = 0; i < nums.size(); i++)
        {
    
    
            int left = i + 1;
            int right = nums.size() - 1;
            if (left >= right)
                break;
            vector<int> Three;
            while (nums[i] + nums[left] + nums[right] != 0 && left < right)
            {
    
    
                if (nums[i] + nums[left] + nums[right] < 0)
                    left++;
                if (nums[i] + nums[left] + nums[right] > 0)
                    right--;
            }
            if (nums[i] + nums[left] + nums[right] == 0&&left!=right)
            {
    
    
                Three.push_back(nums[i]);
                Three.push_back(nums[left]);
                Three.push_back(nums[right]);
                result.insert(Three);
            }
        }
        return vector<vector<int>>(result.begin(),result.end());
    }
};

Guess you like

Origin blog.csdn.net/qq_34811382/article/details/112579278