LeetCode Weekly Contest 127

It is the first time to participate in LeetCode's weekly programming competition, ranking 178 / 4682, which is still acceptable. (The 5-minute time penalty for submitting the wrong answer to the first question is really unbearable, otherwise you can advance to the top 100)

1、1005. Maximize Sum Of Array After K Negations

Given an array A of integers, we must modify the array in the following way: we choose an i and replace A[i] with -A[i], and we repeat this process K times in total. (We may choose the same index i multiple times.)

Return the largest possible sum of the array after modifying it in this way.

Example 1:

Input: A = [4,2,3], K = 1
Output: 5
Explanation: Choose indices (1,) and A becomes [4,-2,3].

Title meaning

Perform K operations on an array (one operation is to invert the positive and negative of a certain number, and can operate on the same number), and find the maximum value of the sum of the array after the operation.

problem solving ideas

Greedy method, to sort the array, first only operate on negative numbers, starting from the smallest. After all operations are completed, if K is not left, return the sum directly; if K is left, it means that all of them have been converted into positive numbers at this time, then operate on the smallest positive number. Judge whether K is a multiple of 2 to decide whether to operate.

class Solution:
    def largestSumAfterKNegations(self, A: List[int], K: int) -> int:
        A.sort()		# 排序
        target = -1
        for i, ele in enumerate(A):
            if K and ele < 0:
                A[i] = -A[i]
                target = i
                K -= 1
            else:
                break
              
        K = K % 2
        if K > 0:		# 需要对最小的正数取反,找到最小的正数
            if target+1<len(A) and A[target]>A[target+1]:
                A[target+1] = -A[target+1]
            else:
                A[target] = -A[target]
                
        return sum(A)

2、1006. Clumsy Factorial

Normally, the factorial of a positive integer n is the product of all positive integers less than or equal to n. For example, factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1.

We instead make a clumsy factorial: using the integers in decreasing order, we swap out the multiply operations for a fixed rotation of operations: multiply (*), divide (/), add (+) and subtract (-) in this order.

For example, clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1. However, these operations are still applied using the usual order of operations of arithmetic: we do all multiplication and division steps before any addition or subtraction steps, and multiplication and division steps are processed left to right.

Additionally, the division that we use is floor division such that 10 * 9 / 8 equals 11. This guarantees the result is an integer.

Implement the clumsy function as defined above: given an integer N, it returns the clumsy factorial of N.

Example 1:

Input: 4
Output: 7
Explanation: 7 = 4 * 3 / 2 + 1

Title meaning

Define a new factorial operation, use + - * / several symbols in turn, and find the final result.

problem solving ideas

Directly simulate this operation, except that when encountering subtraction, the next three digits must be considered for calculation, and the rest of the symbols can be calculated directly from left to right.

class Solution:
    import math
    def clumsy(self, N: int) -> int:
        oper = 0
        ret = N
        N -= 1
        
        while N >= 1:		# N是当前要处理的数
            if oper == 0:	# *
                ret *= N
                oper = (oper+1)%4
                N -= 1
            elif oper == 1:     # /
                ret = math.floor(ret/N)
                oper = (oper+1)%4
                N -= 1
            elif oper == 2:		# +
                ret += N
                oper = (oper+1)%4
                N -= 1
            else:		# -
                if N >= 3:
                    ret -= (math.floor(N*(N-1)/(N-2)))
                    N -= 3
                    oper = 2		# 运算符变成 +
                elif N == 2:
                    ret -= 2
                    return ret
                elif N == 1:
                    ret -= 1
                    return ret
        return ret

3、1007. Minimum Domino Rotations For Equal Row

In a row of dominoes, A[i] and B[i] represent the top and bottom halves of the i-th domino. (A domino is a tile with two numbers from 1 to 6 - one on each half of the tile.)

We may rotate the i-th domino, so that A[i] and B[i] swap values.

Return the minimum number of rotations so that all the values in A are the same, or all the values in B are the same.

If it cannot be done, return -1.

Example 1:

Input: A = [2,1,2,4,2,2], B = [5,2,6,2,3,2]
Output: 2
Explanation: 
The first figure represents the dominoes as given by A and B: before we do any rotations.
If we rotate the second and fourth dominoes, we can make every value in the top row equal to 2, as indicated by the second figure.

Title meaning

Two rows of arrays, at least how many times of exchange, can make the elements of the upper row of arrays or the lower arrays in a row all equal.

problem solving ideas

Direct brute force enumeration. Assuming that after the final adjustment, all the elements in a row are K, enumerate each element of the array A as a possible value of this K, and judge whether the corresponding position of AB is equal to K to determine whether to perform the exchange operation. Add the visit array to deduplicate to speed up the search.

class Solution:
    def minDominoRotations(self, A: List[int], B: List[int]) -> int:
        def tryswap(A, B):
            visit = []
            n = len(A)
            minSwapNum = 99999
            for i,ele in enumerate(A):
                if ele in visit:
                    continue
                visit.append(ele)		# 假设它是最后转化的结果
                swapNum = 0
                for j in range(n):
                    if A[j] == ele:
                        continue
                    elif B[j] == ele:
                        swapNum += 1
                    else:
                        swapNum = 99999
                        break
                minSwapNum = min(minSwapNum, swapNum)
            return minSwapNum
        
        swapNum = min(tryswap(A, B), tryswap(B, A))
        if swapNum == 99999:
            return -1
        return swapNum

4、1008. Construct Binary Search Tree from Preorder Traversal

Return the root node of a binary search tree that matches the given preorder traversal.

(Recall that a binary search tree is a binary tree where for every node, any descendant of node.left has a value < node.val, and any descendant of node.right has a value > node.val. Also recall that a preorder traversal displays the value of the node first, then traversesnode.left, then traverses node.right.)

Example 1:

Input: [8,5,1,7,10,12]
Output: [8,5,10,1,7,null,12]

insert image description here

Title meaning

Rebuilds a binary search tree from a preordered sequence.

problem solving ideas

The first element of the preorder must be the root node. Then find the position of the first element greater than it backwards as K, then list[1:K] is its left subtree, list[K:] is its right subtree, and build a tree recursively.

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def bstFromPreorder(self, preorder: List[int]) -> TreeNode:
        if len(preorder)==0:
            return None
        root = TreeNode(preorder[0])
        
        target = len(preorder)
        for i,ele in enumerate(preorder):
            if ele > preorder[0]:
                target = i
                break
        root.left = self.bstFromPreorder(preorder[1:target])
        root.right = self.bstFromPreorder(preorder[target:])
        
        return root

Guess you like

Origin blog.csdn.net/pku_Coder/article/details/88376409