返回

LeetCode 280 和 316 题解:贪心与数学技巧的巧妙应用

闲谈

贪心与找规律:LeetCode 280 摆动排序

题目简介

给定一个无序数组,将其重新排列成一个摆动数组,即相邻元素之间的差值应尽可能大。

贪心策略

摆动排序的核心思想是贪心,即在每次操作中做出最优选择。我们可以从数组的第一个元素开始,将其与后一个元素比较。如果后一个元素大于前一个元素,则将后一个元素放在前一个元素后面;否则,将后一个元素放在前一个元素前面。这样,我们就可以确保相邻元素之间的差值尽可能大。

代码实现

def wiggleSort(nums):
    for i in range(1, len(nums)):
        if (i % 2 == 0 and nums[i] < nums[i - 1]) or (i % 2 == 1 and nums[i] > nums[i - 1]):
            nums[i], nums[i - 1] = nums[i - 1], nums[i]

时间复杂度

算法的时间复杂度为 O(n),其中 n 是数组的长度。这是因为算法只遍历数组一遍。

空间复杂度

算法的空间复杂度为 O(1),因为算法不需要额外空间。

数学技巧与排序:LeetCode 316 去除重复字母

题目简介

给定一个字符串,去除其中所有重复的字母,并返回一个不含重复字母的最长子字符串。

数学技巧

去除重复字母的关键在于识别出字符串中第一个不重复的字符,并以此为基础构建一个不含重复字母的子字符串。我们可以使用一个哈希表来记录每个字符出现的次数,并通过遍历字符串来找出第一个不重复的字符。

代码实现

def removeDuplicateLetters(s):
    hashmap = {}
    for char in s:
        if char not in hashmap:
            hashmap[char] = 0
        hashmap[char] += 1

    stack = []
    visited = set()
    for char in s:
        hashmap[char] -= 1
        if char not in visited:
            while stack and stack[-1] > char and hashmap[stack[-1]] > 0:
                visited.remove(stack.pop())
            stack.append(char)
            visited.add(char)

    return ''.join(stack)

时间复杂度

算法的时间复杂度为 O(n),其中 n 是字符串的长度。这是因为算法只遍历字符串一遍,并且在每个字符上执行常数时间操作。

空间复杂度

算法的空间复杂度为 O(n),因为算法需要使用哈希表和栈来存储信息。