011 The container with the most water
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;
}
};
014 Longest common prefix
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;
}
};
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.
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;
}
};
015 Sansanowa
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)
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.
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
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());
}
};