LeetCode 中等題解(2)

31 下一個排列

Question

實現獲取下一個排列的函數,算法需要將給定數字序列重新排列成字典序中下一個更大的排列。

如果不存在下一個更大的排列,則將數字重新排列成最小的排列(即升序排列)。

必須原地修改,只允許使用額外常數空間。

以下是一些例子,輸入位於左側列,其相應輸出位於右側列。
1,2,31,3,2
3,2,11,2,3
1,1,51,5,1

Answer

#
# @lc app=leetcode.cn id=31 lang=python3
#
# [31] 下一個排列
#

# @lc code=start
class Solution:
    def nextPermutation(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        for i in range(len(nums)-1, 0, -1):
            if nums[i] > nums[i-1]:
                res_nums = nums[i:]
                res_nums.sort()
                nums[i:] = res_nums
                for j in range(i, len(nums)):
                    if nums[j] > nums[i-1]:
                        nums[j], nums[i-1] = nums[i-1], nums[j]
                        break
                return
        nums.sort()

# @lc code=end


PS:設計思路:
1.從數組右側向左開始遍歷,找是否存在nums[i]>nums[i-1]的情況,
2.如果不存在這種nums[i]>nums[i-1]情況 ,for循環會遍歷到i==0(也就是沒有下一個排列),此時按題意排成有序Arrays.sort()
3.如果存在,則將從下標i到nums.length()的部分排序,然後在排過序的這部分中遍歷找到第一個大於nums[i-1]的數,並與nums[i-1]交換位置

33 搜索旋轉排序數組

Question

假設按照升序排序的數組在預先未知的某個點上進行了旋轉。

( 例如,數組 [0,1,2,4,5,6,7] 可能變爲 [4,5,6,7,0,1,2] )。

搜索一個給定的目標值,如果數組中存在這個目標值,則返回它的索引,否則返回 -1

你可以假設數組中不存在重複的元素。

你的算法時間複雜度必須是 O(log n) 級別。

示例 1:

輸入: nums = [4,5,6,7,0,1,2], target = 0
輸出: 4

示例 2:

輸入: nums = [4,5,6,7,0,1,2], target = 3
輸出: -1

Answer

#
# @lc app=leetcode.cn id=33 lang=python3
#
# [33] 搜索旋轉排序數組
#

# @lc code=start
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        def find_rotate_index(left, right):
            if nums[left] < nums[right]:
                return 0
            
            while left <= right:
                pivot = (left + right) // 2
                if nums[pivot] > nums[pivot + 1]:
                    return pivot + 1
                else:
                    if nums[pivot] < nums[left]:
                        right = pivot - 1
                    else:
                        left = pivot + 1
                
        def search(left, right):
            """
            Binary search
            """
            while left <= right:
                pivot = (left + right) // 2
                if nums[pivot] == target:
                    return pivot
                else:
                    if target < nums[pivot]:
                        right = pivot - 1
                    else:
                        left = pivot + 1
            return -1
        
        n = len(nums)
        
        if n == 0:
            return -1
        if n == 1:
            return 0 if nums[0] == target else -1 
        
        rotate_index = find_rotate_index(0, n - 1)
        
        # if target is the smallest element
        if nums[rotate_index] == target:
            return rotate_index
        # if array is not rotated, search in the entire array
        if rotate_index == 0:
            return search(0, n - 1)
        if target < nums[0]:
            # search on the right side
            return search(rotate_index, n - 1)
        # search on the left side
        return search(0, rotate_index)


# @lc code=end


238 除自身以外數組的乘積

Question

給你一個長度爲 n 的整數數組 nums,其中 n > 1,返回輸出數組 output ,其中 output[i] 等於 nums 中除 nums[i] 之外其餘各元素的乘積。

示例:

輸入: [1,2,3,4]
輸出: [24,12,8,6]

提示:題目數據保證數組之中任意元素的全部前綴元素和後綴(甚至是整個數組)的乘積都在 32 位整數範圍內。

說明:不要使用除法,且在 O(n) 時間複雜度內完成此題。

進階:
你可以在常數空間複雜度內完成這個題目嗎?( 出於對空間複雜度分析的目的,輸出數組不被視爲額外空間。)

Answer

#
# @lc app=leetcode.cn id=238 lang=python3
#
# [238] 除自身以外數組的乘積
#


# @lc code=start
class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        results = []
        left, right = 1, 1
        for i in range(len(nums)):
            results.append(left)
            left *= nums[i]
        for i in range(len(nums) - 1, -1, -1):
            results[i] = results[i] * right
            right *= nums[i]
        return results


# @lc code=end

PS:相當於是先得到要求解的元素左側的連續積,然後再求得右側的連續積,之後再進行相乘即可。

287 尋找重複數

Question

給定一個包含 n + 1 個整數的數組 nums,其數字都在 1 到 n 之間(包括 1 和 n),可知至少存在一個重複的整數。假設只有一個重複的整數,找出這個重複的數。

示例 1:

輸入: [1,3,4,2,2]
輸出: 2

示例 2:

輸入: [3,1,3,4,2]
輸出: 3

說明:

  1. 不能更改原數組(假設數組是隻讀的)。
  2. 只能使用額外的 O(1) 的空間。
  3. 時間複雜度小於 O(n2) 。
  4. 數組中只有一個重複的數字,但它可能不止重複出現一次。

Answer

#
# @lc app=leetcode.cn id=287 lang=python3
#
# [287] 尋找重複數
#


# @lc code=start
class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        left = 1
        right = len(nums) - 1
        while (left < right):
            mid = (left + right) // 2
            count = 0
            for num in nums:
                if (num <= mid):
                    count += 1
            if (count <= mid):
                left = mid + 1
            else:
                right = mid
        return left


# @lc code=end

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章