Blue Bridge Cup punch (220118)

Posted by slionheart on Fri, 21 Jan 2022 06:04:31 +0100

Blue Bridge Cup punch (220118)

Title No.: 2

Title details:

Give you two non empty linked lists to represent two non negative integers. They store each number in reverse order, and each node can store only one number.

Please add the two numbers and return a linked list representing sum in the same form.

You can assume that neither number starts with 0 except the number 0.

Example 1:

Input: l1 = [2,4,3], l2 = [5,6,4]
Output:[7,0,8]
Explanation: 342 + 465 = 807.

Example 2:

Input: l1 = [0], l2 = [0]
Output:[0]

Example 3:

Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
Output:[8,9,9,9,0,0,0,1]

Tips:

  • The number of nodes in each linked list is within the range [1, 100]
  • 0 <= Node.val <= 9
  • The number represented in the title data guarantee list does not contain leading zeros

Problem solving ideas:

Idea 1:

Add directly without conversion

Two linked lists in reverse order are added from the first node (bit). If the result is less than 10, it is saved directly. If the result is greater than 10, the remainder result is saved, and one is added when the next bit is added.

It should be noted that the number of digits of the result should be considered when establishing the linked list. It is better to be longer than one node of the longest linked list.

Idea 2:

Add after conversion, and then transfer it back to the linked list in reverse order

code implementation

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode *head = nullptr, *tail = nullptr;
        int carry = 0;
        while (l1 || l2) {
            int n1 = l1 ? l1->val: 0;
            int n2 = l2 ? l2->val: 0;
            int sum = n1 + n2 + carry;
            if (!head) {
                head = tail = new ListNode(sum % 10);
            } else {
                tail->next = new ListNode(sum % 10);
                tail = tail->next;
            }
            carry = sum / 10;
            if (l1) {
                l1 = l1->next;
            }
            if (l2) {
                l2 = l2->next;
            }
        }
        if (carry > 0) {
            tail->next = new ListNode(carry);
        }
        return head;
    }
};

Title No.: 135

Title details:

n children stand in a row. Give you an integer array of ratings to represent the score of each child.

You need to distribute candy to these children according to the following requirements:

  • Each child is assigned at least one candy.
  • Children with higher scores from two adjacent children will get more candy.

Please distribute candy to each child, calculate and return the minimum number of candy to be prepared.

Example 1:

Input: ratings = [1,0,2]
Output: 5
 Explanation: you can distribute 2, 1 and 2 candies to the first, second and third children respectively.

Example 2:

Input: ratings = [1,2,2]
Output: 4
 Explanation: you can distribute 1, 2 and 1 candy to the first, second and third children respectively.
     The third child only got one candy, which met two conditions in the question.

Tips:

  • n == ratings.length
  • 1 <= n <= 2 * 104
  • 0 <= ratings[i] <= 2 * 104

Problem solving ideas:

This problem uses greedy algorithm

First, we need to ensure that everyone has a candy. Then, we traverse each element of the array twice in turn. For the first time, we guarantee that children with higher scores on the left will get more candy, and for the second time, we guarantee that children with higher scores on the right will get more candy.

Take example 1 as an example. The number of allocated sweets in initialization is [1,1,1], the first traversal result is [1,1,2], and the second traversal result is [2,1,2]

Code implementation:

class Solution {
public:
    int candy(vector<int>& ratings) 
    {
		int a=ratings.size();
        if(a<2) return 1;
        vector<int>num(a,1);//Create an array with integer named num, size a, and size 1 for each array element
        for(int i=1;i<a;i++)
            if(ratings[i]>ratings[i-1])
                num[i]=num[i-1]+1;
        for(int i=a;i>0;i--)
            if(ratings[i]<ratings[i-1])
                num[i-1]=max(num[i-1],num[i]+1);
        return accumulate(num.begin(),num.end(),0);//Summation function, convenient summation
    }
};

New knowledge

vector<int>num(a,1);//Define array
//Create an array with integer named num, size a, and size 1 for each array element
//Vector < type > array name (number of elements, size of elements)
//After checking the book, I feel that there is a problem in understanding. This statement will be updated after reading C++ primer
 num[i-1]=max(num[i-1],num[i]+1);
//Select the larger of the two incoming numbers
accumulate(num.begin(),num.end(),0);
/*
accumulate()The summation function is defined in the header file numeric, so you need to #include < numeric > before using it. It has two overload forms, one does not need custom data type processing, and the other needs to be defined.

The most commonly used summation in the above example does not require user-defined data type processing. The third parameter is the initial value, that is, all values from begin to end are accumulated from this value. Here, the initial value is set to 0, that is, only the cumulative sum of values from begin to end is calculated without adding the initial value:
*/