python3__leecode/1743. Restore arrays from adjacent element pairs

Posted by artweb on Sat, 15 Jan 2022 04:41:30 +0100

1, Brush question content

Original question link

https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/

Content description

There is an integer array nums composed of n different elements, but you can't remember the specific content. Fortunately, you still remember each pair of adjacent elements in num.

Give you a two-dimensional integer array adjacentPairs with a size of n - 1, where each adjacentPairs[i] = [ui, vi] indicates that the elements ui and VI are adjacent in nums.

The topic data ensures that all adjacent element pairs composed of elements nums[i] and nums[i+1] exist in adjacentPairs. The existing forms may be [nums[i], nums[i+1]], or [nums[i+1], nums[i]]. These adjacent element pairs can appear in any order.

Returns the original array nums. If there are multiple answers, just return any one of them.

Example 1:
Input: adjacentPairs = [[2,1],[3,4],[3,2]]
Output: [1,2,3,4]
Explanation: all adjacent element pairs of an array are in adjacentPairs.
In particular, adjacentPairs[i] only indicates that two elements are adjacent, and its left-right order is not guaranteed.

Example 2:
Input: adjacentPairs = [[4,-2],[1,4],[-3,1]]
Output: [- 2,4,1, - 3]
Explanation: there may be negative numbers in the array.
Another answer is [- 3,1,4, - 2], which will also be regarded as the correct answer.

Example 3:
Input: adjacentPairs = [[100000,-100000]]
Output: [100000, - 100000]

Tips:
nums.length == n
adjacentPairs.length == n - 1
adjacentPairs[i].length == 2
2 <= n <= 105
-105 <= nums[i], ui, vi <= 105
The title data ensures that there are some array nums with adjacentPairs as element pairs

2, Problem solving method

1. Method 1: one way construction (hash table counting)

According to the meaning of the question, since all adjacent relationships will appear in numnumnums, assume that one of the legal arrays is ansans and the length is nn.

Obviously, ans[0]ans[0] and ans[n - 1]ans[n − 1] have only one pair of adjacent relationships in numnumnums, while other ans[i]ans[i] have two pairs of adjacent relationships.

Therefore, we can use the "hash table" to count the values appearing in numnumnums, find the "once" value as the first place of the ansans value, and then carry out "one-way construction" according to the given adjacency relationship. In order to find out what the adjacent numbers of a certain number are, we also need to open another "hash table" to record the adjacency relationship.

class Solution:
    def restoreArray(self, adjacentPairs: List[List[int]]) -> List[int]:
        m = n = len(adjacentPairs)
        n += 1
        cnts = defaultdict(int)
        hashmap = defaultdict(list)
        for a, b in adjacentPairs:
            cnts[a] += 1
            cnts[b] += 1
            hashmap[a].append(b)
            hashmap[b].append(a)
        start = -1
        for i, v in cnts.items():
            if v == 1:
                start = i
                break
        ans = [0] * n
        ans[0] = start
        ans[1] = hashmap[start][0]
        for i in range(2, n):
            x = ans[i - 1]
            for j in hashmap[x]:
                if j != ans[i - 2]:
                    ans[i] = j
        return ans

Time complexity: O(n)O(n)
Space complexity: O(n)O(n)

2. Method 2: Bidirectional Construction (double pointer)

In solution 1, we use the hash table to count the source of the first ansans as the starting point for "one-way construction".

Starting from the middle position of the qq array, add one of the elements to the middle position, and use the "double pointer" to expand to "both sides" (l and r point to the left and right positions to be inserted respectively).

When the l pointer and r pointer have n values directly, it indicates that the whole ans construction is completed. We can take the numerical output within the range of [l + 1, r - 1] as the answer.

class Solution:
    N = 10 ** 6 + 10
    q = [0] * N

    def restoreArray(self, adjacentPairs: List[List[int]]) -> List[int]:
        m = len(adjacentPairs)
        n = m + 1
        hashmap = defaultdict(list)
        for a, b in adjacentPairs:
            hashmap[a].append(b)
            hashmap[b].append(a)
        l = self.N // 2
        r = l + 1
        std = adjacentPairs[0][0]
        lt = hashmap[std]
        self.q[l] = std
        l -= 1
        self.q[r] = lt[0]
        r += 1
        if len(lt) > 1:
            self.q[l] = lt[1]
            l -= 1
        while (r-1)-(l+1)+1<n:
            alt = hashmap[self.q[l+1]]
            j = l
            for i in alt:
                if i != self.q[l+2]:
                    self.q[j] = i
                    j -= 1
            l = j
            
            blt = hashmap[self.q[r-1]]
            j = r
            for i in blt:
                if i != self.q[r - 2]:
                    self.q[j] = i
                    j += 1
            r = j
        ans = [0] * n
        for idx in range(n):
            ans[idx] = self.q[idx+l+1]
        return ans

Time complexity: O(n)O(n)
Space complexity: O(n)O(n)

Topics: Python leetcode