zoukankan      html  css  js  c++  java
  • 【Leetcode】技巧系列

     【Leetcode-6】

    一、题目:Z字形变换

      将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

    二、代码:

    def convert(self, s: str, numRows: int) -> str:
            """
            设置n个list,一个个往里填,行到0或者n-1就转方向,空的位置不管
            """
            res = [''] * numRows
            direction = 1  # 代表向下,行+1
            r = 0  # 当前处在第0行
            for item in s:
                res[r] += item
                r = r+1 if direction > 0 else r-1  # 下一步要走的行
                if r == numRows or r < 0:  # 行超出边界
                    r = r-2 if r == numRows else r+2  # 退2步或进2步
                    direction = -direction  # 换方向
            res = ''.join(res)
            return res

    【Leetcode-26】

    一、题目:删除有序数组中的重复项

      给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。

      不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

    二、代码:

    def removeDuplicates(self, nums: List[int]) -> int:
            """
            两个指针,一个指向处理完的位置,一个指向待处理的位置,若待处理的值和处理完的不相同则复制过来,处理完指针后移,返回处理完指针的位置
            """
            if len(nums) == 0:
                return 0 
            p = 0
            for i, item in enumerate(nums):
                if item != nums[p]:
                    p += 1
                    nums[p] = item
            return p+1  # 数组长度为指向位置+1

    【Leetcode-27】

    一、题目:移除元素

      给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

      不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

      元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

    二、代码:

    def removeElement(self, nums: List[int], val: int) -> int:
            p = -1  # 处理完的下标
            for i in range(len(nums)):
                if val != nums[i]:
                    p += 1
                    nums[p] = nums[i]
            return p+1

    【Leetcode-75】

    一、题目:颜色分类

      给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

      此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

    二、代码:

    def sortColors(self, nums: List[int]) -> None:
            """
            Do not return anything, modify nums in-place instead.
            """
            n = len(nums)
            if n == 0:
                return nums
            p0 = p1 = 0
            for i in range(n):
                if nums[i] == 0:
                    nums[i], nums[p0] = nums[p0],  nums[i]
                    if nums[i] == 1:
                        nums[i], nums[p1] = nums[p1],  nums[i]
                    p0 += 1
                    p1 += 1
                elif nums[i] == 1:
                    nums[i], nums[p1] = nums[p1],  nums[i]
                    p1 += 1

    【Leetcode-54】

    一、题目:螺旋矩阵

      给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

    二、代码:

    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
            """
            遍历过或者超出边界的为墙,撞墙则转方向,否则朝当前方向走,进来的地方为(0,-1)
            """
            m, n = len(matrix), len(matrix[0])
            directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
            dir_idx = 0  # 当前方向
            x, y = 0, -1  # 当前所处位置
            res = []
            visited = set()
            for _ in range(m*n):  # 所有数
                direction = directions[dir_idx]
                new_x, new_y = x + direction[0], y + direction[1]
                if not (0<=new_x<m and 0<=new_y<n and (new_x, new_y) not in visited):
                    # 撞墙或者已经遍历
                    dir_idx = (dir_idx+1) % len(directions)
                    direction = directions[dir_idx]
                    new_x, new_y = x + direction[0], y + direction[1]
                visited.add((new_x, new_y))
                res.append(matrix[new_x][new_y])
                x, y = new_x, new_y
            return res

    【Leetcode-56】

    一、题目:合并区间

      以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。

    二、代码:

     def merge(self, intervals: List[List[int]]) -> List[List[int]]:
            res = []
            if len(intervals) == 0:
                return res
    
            intervals.sort(key=lambda x: x[0])
            p = intervals[0]
            for item in intervals[1:]:
                if item[0] <= p[1]:
                    p = [min(p[0], item[0]), max(p[1], item[1])]
                else:
                    res.append(p)
                    p = item
            res.append(p)
            return res

    【Leetcode-88】

    一、题目:合并两个有序数组

      给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

      初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。

    二、代码:

    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
            """
            逆向双指针,避免额外空间,每次选最大的填入尾部
            """
            p = m + n - 1 # 最终结果指针
            p1 = m - 1
            p2 = n - 1
            while p >= 0:
                val1 = nums1[p1] if p1 >= 0 else float('-inf')
                val2 = nums2[p2] if p2 >= 0 else float('-inf')
                if val1 > val2:
                    nums1[p] = val1
                    p1 -= 1
                else:
                    nums1[p] = val2
                    p2 -= 1
                p -= 1

    【Leetcode-128】

    一、题目:最长连续序列

      给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

    二、代码:  

    def longestConsecutive(self, nums: List[int]) -> int:
            look_up = {}
            for item in nums:
                look_up[item] = 1
            max_len = 0
            for item in nums:
                if item-1 not in look_up:
                    this_len = 1
                    while item + 1 in  look_up:
                        this_len += 1
                        item += 1
                    max_len = max(max_len, this_len)
            return max_len

    【Leetcode-169】

    一、题目:多数元素

      给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

      你可以假设数组是非空的,并且给定的数组总是存在多数元素。

    二、代码:

    ef majorityElement(self, nums: List[int]) -> int:
            major = nums[0]
            count = 1
            for item in nums[1:]:
                if item == major:
                    count += 1
                else:
                    count -= 1
                if count == 0:
                    major = item
                    count = 1
            return major

    【Leetcode-238】

    一、题目:除自身以外的乘积

      给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。

    二、代码:

    def productExceptSelf(self, nums: List[int]) -> List[int]:
            n = len(nums)
            output = [1]*n
            # 计算每个位置左边的乘积
            for i in range(1, n):
                output[i] = nums[i-1] * output[i-1]
            # 累乘右边的乘积
            right_val = 1
            for i in reversed(range(n)):
                output[i] = output[i] * right_val
                right_val = nums[i] * right_val
            return output

    【Leetcode-240】

    一、题目:搜索二维矩阵2

      编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

      每行的元素从左到右升序排列。
      每列的元素从上到下升序排列。

    二、代码:

    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
            m, n = len(matrix), len(matrix[0])
            i, j = 0, n-1
            while i <= m-1 and j >= 0:
                if matrix[i][j] == target:
                    return True
                if target < matrix[i][j]:
                    j -= 1
                else:
                    i += 1
            return False

    【Leetcode-280】

    一、题目:摆动排序

      给你一个无序的数组 nums, 将该数字 原地 重排后使得 nums[0] <= nums[1] >= nums[2] <= nums[3]...。答案不唯一。

    二、代码:

    def wiggleSort(self, nums: List[int]) -> None:
            """
            逐位与前一位比较,不对则对换,一次大一次小
            """
            n = len(nums)
            if n <= 1:
                return nums
            flag = 1  # 要求比前面的大,也可以等于
            for i in range(1, n):
                if flag > 0:
                    if nums[i] < nums[i-1]:
                        nums[i], nums[i-1] = nums[i-1], nums[i]
                else:  # 要求比前面的小,也可以等于
                    if nums[i] > nums[i-1]:
                        nums[i], nums[i-1] = nums[i-1], nums[i]
                flag = -flag
            return nums

    【Leetcode-283】

    一、题目:移动零

      给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

    二、代码:

    def moveZeroes(self, nums: List[int]) -> None:
            """
            Do not return anything, modify nums in-place instead.
            """
            """
            p指向已处理完序列的尾部,尾部向后扩展,遇到的字符不是0则调换到前面
            """
            p = 0
            for i in range(len(nums)):
                # if i == 0:
                #     continue
                if nums[i] != 0:
                    nums[p], nums[i] = nums[i], nums[p]
                    p += 1

    【Leetcode-383】

    一、题目:赎金信

      给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。

      (题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)

    二、代码:

    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
            """
            a中出现频率<b中出现频率
            """
            def get_cnt(s):
                res = dict()
                for item in s:
                    cnt = res.get(item, 0)
                    res[item] = cnt + 1
                return res
            cnt1 = get_cnt(ransomNote)
            cnt2 = get_cnt(magazine)
            for k, n1 in cnt1.items():
                n2 = cnt2.get(k, 0)
                if n1 > n2:
                    return False
            return True

    【Leetcode-406】

    一、题目:根据身高重建队列

      假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。

      请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。

    二、代码:

    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
            """
            先按身高排序,再插队
            """
            people.sort(key=lambda x: (-x[0], x[1]))
            res = []  # 已经排好队的人
            for item in people:
                if len(res) > item[1]:
                    res.insert(item[1], item)
                else:
                    res.append(item)
            return res

    【Leetcode-448】

    一、题目:找到所有数组中消失的数字

    二、代码:

    def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
            n = len(nums)
            res = []
            for i in range(n):
                nums[i] -= 1
            for item in nums:
                nums[item % n] += n
            for i, item in enumerate(nums):
                if item < n:
                    res.append(i+1)
            return res

    【Leetcode-581】

    一、题目:最短无序连续子数组

      给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。

      请你找出符合题意的 最短 子数组,并输出它的长度。

    二、代码:

    def findUnsortedSubarray(self, nums: List[int]) -> int:
            nums_new = sorted(nums)
            n = len(nums_new)
            start, end = -1, n
            for i in range(n):
                if nums[i] != nums_new[i]:
                    end = i
                if nums[n-i-1] != nums_new[n-i-1]:
                    start = n-i-1
            if start == -1:
                return 0
            else:
                return end-start+1

    【Leetcode-621】

    一、题目:任务调度器

      给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。

      然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。

      你需要计算完成所有任务所需要的 最短时间 。

    二、代码:

    def leastInterval(self, tasks: List[str], n: int) -> int:
            """
            最重复的任务的次数为k,设置k个桶,相同任务不能放入同一桶,即可满足要求,求桶里任务量(空闲也算任务),桶的大小为n+1,即每个桶执行完任务就填入冷却任务(此时也算执行其他任务)。但当冷却时间较小时,需要扩大桶的容量,导致每个桶都被填满,此时需要的时间为任务数。因此最终时间选择最大值。
            """
            from collections import Counter
            cnt = Counter(tasks)
            cnt_list = list(cnt.values())
            k = max(cnt_list)
            # 前k-1个桶都装满,消耗的时间
            t1 = (k-1)*(n+1)
            # 最后一个桶不一定装满,装的数为数量为k的任务个数
            t2 = len([t for t in cnt_list if t==k])
            return t1+t2 if t1+t2 > len(tasks) else len(tasks)
    博文转载请注明出处。
  • 相关阅读:
    原来这样就可以开发出一个百万量级的Android相机
    微信读书这样排版,看过的人都很难忘!
    AI小白快上车!这是发往高薪职位的车!
    短视频APP是如何开启你的美好生活的?
    自从我这样撸代码以后,公司网页的浏览量提高了107%!
    如果想成为一名顶尖的前端,这份书单你一定要收藏!
    老板今天问我为什么公司的数据库这么烂,我是这样回答的......
    MapReduce Notes
    HDFS Architecture Notes
    BloomFilter
  • 原文地址:https://www.cnblogs.com/EstherLjy/p/14608600.html
Copyright © 2011-2022 走看看