LeetCode473. Matches to make a square

Table of contents

Article directory

1. Title

2. Problem-solving ideas

3. Knowledge summary

1. Detailed explanation of the usage of C++ sort() sorting function

2.accumulate() function

Summarize


1. Title

You will get an integer array matchsticks, where matchsticks[i] is the length of the i-th matchstick. You need to use all the matchsticks  to form a square. You cannot break any matchsticks, but you can connect them together, and each matchstick must be used once .

Returns true if you can make this square, false otherwise.

Example 1:

Input: matchsticks = [1,1,2,2,2]
Output: true
Explanation: It can form a square with a side length of 2 and two matches on each side.

Example 2:

Input: matchsticks = [3,3,3,3,4]
Output: false
Explanation: All matches cannot be used to form a square.

hint:

1 <= matchsticks.length <= 15
1 <= matchsticks[i] <= 108

2. Problem-solving ideas

First calculate the total length of all matches totallen. If totallen is not a multiple of 4, then it is impossible to form a square and return false. When totallen is a multiple of 44, the length of each side is totallen/4, and edges are used to record the total length of matches placed on the four sides. For the index match, try to put it into one of the edges so that the total length of the match on that edge does not exceed len, and then continue to enumerate the placement of the index+1 match. If all matches have been placed , then it means that it can be formed into a square.

In order to reduce the search volume, the match lengths need to be sorted from large to small.

class Solution {
public:
    bool dfs(int index,vector<int>& matchsticks,vector<int>& edges,int len){
        //递归结束条件
        if(index==matchsticks.size())
        {
            return true;
        }
        for(int i=0;i<edges.size();i++){
            edges[i]+=matchsticks[index];
            if(edges[i]<=len && dfs(index+1,matchsticks,edges,len)){
                return true;
            }
            edges[i]-=matchsticks[index];
        }
        return false;
    }
    bool makesquare(vector<int>& matchsticks) {
        int index=0;
        int totallen=accumulate(matchsticks.begin(),matchsticks.end(),0);
        int len=totallen/4;
        if((totallen%4)!=0){
            return false;
        }
        vector<int> edges(4);
        //降序排序
        sort(matchsticks.begin(),matchsticks.end(),std::greater<int>());
        if(dfs(index,matchsticks,edges,len)){
            return true;
        }
        else{
            return false;
        }
    }
};

3. Knowledge summary

1. Detailed explanation of the usage of C++ sort() sorting function

This function is specially used to sort elements within a specified range in a container or ordinary array. The sorting rule defaults to ascending order by the size of the element value. In addition, we can also choose other sorting rules provided by the standard library (such as descending std::greater<T>sorting rules), and you can even customize the sorting rules.

The sort() function is implemented based on quick sort

The sort() function is limited by the underlying implementation. It only works with ordinary arrays and some types of containers. In other words, only ordinary arrays and containers that meet the following conditions can use the sort() function:

  1. The iterator type supported by the container must be a random access iterator. This means that sort() only supports three containers: array, vector, and deque.
  2. If the elements in the specified area in the container are sorted in ascending order by default, the element type must support <the less than operator; similarly, if other sorting rules provided by the standard library are selected, the element type must also support the comparison operator used by the underlying implementation of the rule;
  3. When the sort() function implements sorting, it needs to exchange the storage locations of elements in the container. In this case, if a custom class object is stored in the container, the move constructor and move assignment operator must be provided inside the class.

For elements with equal values ​​in the specified range, the sort() function cannot guarantee that their relative positions will not change.

The sort() function is located <algorithm>in the header file, so before using this function, the following statements should be included in the program:

#include <algorithm>

The sort() function has 2 uses, and their syntax formats are:

//对 [first, last) 区域内的元素做默认的升序排序
void sort (RandomAccessIterator first, RandomAccessIterator last);
//按照指定的 comp 排序规则,对 [first, last) 区域内的元素进行排序
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

Example:

#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector
//以普通函数的方式实现自定义排序规则
bool mycomp(int i, int j) {
    return (i < j);
}
//以函数对象的方式实现自定义排序规则
class mycomp2 {
public:
    bool operator() (int i, int j) {
        return (i < j);
    }
};

int main() {
    std::vector<int> myvector{ 32, 71, 12, 45, 26, 80, 53, 33 };
    //调用第一种语法格式,对 32、71、12、45 进行排序
    std::sort(myvector.begin(), myvector.begin() + 4); //(12 32 45 71) 26 80 53 33
    //调用第二种语法格式,利用STL标准库提供的其它比较规则(比如 greater<T>)进行排序
    std::sort(myvector.begin(), myvector.begin() + 4, std::greater<int>()); //(71 45 32 12) 26 80 53 33
   
    //调用第二种语法格式,通过自定义比较规则进行排序
    std::sort(myvector.begin(), myvector.end(), mycomp2());//12 26 32 33 45 53 71 80
    //输出 myvector 容器中的元素
    for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) {
        std::cout << *it << ' ';
    }
    return 0;
}

The average time complexity of this function to implement sorting is N*log2N(where N is the distance between last and first in the specified area [first, last)).

2.accumulate() function

Accumulate takes three formal parameters: the first two formal parameters specify the range of elements to be accumulated, and the third formal parameter is the initial value of accumulation.
The accumulate function sets one of its internal variables to a specified initial value and then accumulates the values ​​of all elements in the input range based on this initial value. The accumulate algorithm returns the accumulated result, and its return type is the type of its third actual parameter.
You can use accumulate to connect elements in string vector containers:

string sum = accumulate(v.begin() , v.end() , string(" "));

But for custom data types, we need to write a callback function ourselves to process the custom data, and then use it as the fourth parameter of accumulate();

#include <vector>
#include <string>
using namespace std;
 
struct Grade
{
	string name;
	int grade;
};
 
int main()
{
	Grade subject[3] = {
		{ "English", 80 },
		{ "Biology", 70 },
		{ "History", 90 }
	};
 
	int sum = accumulate(subject, subject + 3, 0, [](int a, Grade b){return a + b.grade; });
	cout << sum << endl;
 
	system("pause");
	return 0;
}

4. Summary

When you write a recursive function, you must tell it when to stop the recursion.

Every recursive function has two parts: the baseline condition and the recursive condition. Recursive conditions refer to the function calling itself, while baseline conditions refer to the function no longer calling itself, thereby avoiding an infinite loop.

Guess you like

Origin blog.csdn.net/weixin_54106682/article/details/125089375