Python数据结构和算法笔记四:列表list

列表list

  • 时间复杂度:

  • 查找元素,通过下标查找:O(1)

  • 1、支持动态扩容的线性结构,下标访问

  • 2、超出容量之后,会开辟新内存,并复制旧数据

  • 3、Python list可以包含不同的数据类型(元素的类型可以是list、string、tuple…)

  • 4、业务代码和题目当中最常用的一种数据结构

  • 5、L = [] 或者 L= list() 来创建(这两种方式等价)

  • 练习:list数据类型的注意点(坑)

    • # 1、如何初始化一个元素都相同的一维list
      
      # 第一种方式:直接先创建一个list,然后for循环遍历数值并添加进list
      l = []
      for _ in range(10):
      	l.append(5)
      print(l) # [5,5,5,5,5,5,5,5,5,5]
      
      # 第二种方式:使用Python list提供的语法糖
      l = [5]*10
      
    • #2、如何初始化一个元素都相同的二维list(有一个坑在这里)
      def init_matrix(val,rows, cols):
      	return [[val]*cols]*rows # 这种写法会有一个坑,引用了同一个对象
      	# return [[val]*cols for _ in range(rows)] # 应该这样写
      	
      ll = init_matrix(0, 3, 4)
      print(ll) # [[0,0,0],[0,0,0],[0,0,0]]
      ll[0][0] = 100
      print(ll) # [[100,0,0],[100,0,0],[100,0,0]]
      
      # 解释:因为第一种return写法中的list中每一个元素都是指向同一个子list对象(语法糖*的问题),而第二种return写法中的list中每个元素指向的子list都是不同的对象
      # 可以使用可视化网站查看http://pythontutor.com/live.html#mode=edit
      
    • 在这里插入图片描述

list练习
两数之和
  • 解法:

    • 1、暴力解法:使用两次for循环遍历,时间复杂度:O(n^2)

    • 2、空间换时间:使用dict存储,只使用一次for循环,O(n)

    • 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
      
      你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
      示例:
      
      给定 nums = [2, 7, 11, 15], target = 9
      
      因为 nums[0] + nums[1] = 2 + 7 = 9
      所以返回 [0, 1]
      
    • class Solution(object):
          def twoSum(self, nums, target):
              """
              :type nums: List[int]
              :type target: int
              :rtype: List[int]
              """
              d = {}
              for i, num in enumerate(nums):
                  n = target - num
                  if n in d:
                      return [d[n],i]
                  d[num] = i
              return []
      
按奇偶排序数组
  • 解法:

    • 1、在内存空间中开辟新的list空间用来存储奇数以及偶数,空间复杂度会高

    • 2、使用指针方式,不开辟新的内存空间

    • 给定一个非负整数数组 A,返回一个数组,在该数组中, A 的所有偶数元素之后跟着所有奇数元素。
      
      你可以返回满足此条件的任何数组作为答案。
      
      示例:
      输入:[3,1,2,4]
      输出:[2,4,3,1]
      输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受。
      
      提示:
      1 <= A.length <= 5000
      0 <= A[i] <= 5000
      
    • # 按奇偶排序数组
      # class Solution(object):
      #     def odd(self, n):
      #         return n % 2 == 1
          
      #     def even(self, n):
      #         return n % 2 == 0
      
      #     def sortArrayByParity(self, A):
      #         """
      #         :type A: List[int]
      #         :rtype: List[int]
      #         """
      #         L = []
      #         even = list(filter(self.even, A))
      #         odd  = list(filter(self.odd, A))
      #         L = even + odd
      #         return L
      class Solution(object):
          
          def sortArrayByParity(self, A):
              """
              :type A: List[int]
              :rtype: List[int]
              """
              beg, end = 0, len(A)-1
              while True:
                  while A[beg] % 2 == 0 and beg < end:
                      beg += 1
                  while A[end] % 2 == 1 and beg < end:
                      end -= 1 
                  if beg >= end:
                      break
                  A[beg], A[end] = A[end], A[beg]
              return A
      
搜索二维矩阵 II
  • 解法:

    • 1、for循环两次,O(m*n)

    • 2、也是两次for循环,第二次for循环是使用二分查找,O(m*logn)

    • 3、使用指针方式,只使用一次for循环,O(m+n)

    • 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:
      
      每行的元素从左到右升序排列。
      每列的元素从上到下升序排列。
      示例:
      
      现有矩阵 matrix 如下:
      [
        [1,   4,  7, 11, 15],
        [2,   5,  8, 12, 19],
        [3,   6,  9, 16, 22],
        [10, 13, 14, 17, 24],
        [18, 21, 23, 26, 30]
      ]
      
      给定 target = 5,返回 true。
      给定 target = 20,返回 false。
      
    • class Solution(object):
          def searchMatrix(self, matrix, target):
              """
              :type matrix: List[List[int]]
              :type target: int
              :rtype: bool
              """
              if not matrix:
                  return False
              rows = len(matrix)
              cols = len(matrix[0])
              i, j = 0, cols-1
              while i < rows and j >= 0:
                  val = matrix[i][j]
                  if target == val:
                      return True
                  elif target < val:
                      j -= 1
                  else:
                      i += 1
              return False
              
      
      def test_searchMatrix(): # 测试
          M = [
              [1,   4,  7, 11, 15],
              [2,   5,  8, 12, 19],
              [3,   6,  9, 16, 22],
              [10, 13, 14, 17, 24],
              [18, 21, 23, 26, 30]
              ]
      
          assert Solution().searchMatrix(M, 5) == True
          assert Solution().searchMatrix(M, 20) == False
      # 测试命令:when-changed -r -v -1 'filepath' pytest -s 'filepath' 
      
移除元素
  • 解法:

    • 1、反向遍历。如果使用正向遍历的过程,删除list的多个元素的同时会导致list内部数据会变动从而index值会变,会比较麻烦

    • 2、使用指针

    • 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
      不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
      元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
      
      示例 1:
      给定 nums = [3,2,2,3], val = 3,
      函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
      你不需要考虑数组中超出新长度后面的元素。
      
      示例 2:
      给定 nums = [0,1,2,2,3,0,4,2], val = 2,
      函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
      注意这五个元素可为任意顺序。
      你不需要考虑数组中超出新长度后面的元素。
      
      
    • class Solution(object):
          def removeElement(self, nums, val):
              """
              :type nums: List[int]
              :type val: int
              :rtype: int
              """
              # 反向遍历
              # for i in range(len(nums)-1, -1, -1):
              #     if nums[i] == val:
              #         nums.pop(i)
              # return len(nums)
      
              # 使用指针
              i = 0
              for j in range(len(nums)):
                  if nums[j] != val:
                      # nums[i] = nums[j]
                      i += 1
              return i
      
      def test_removeElement():
          print()
          nums = [3,2,2,3]
          val = 3
          nums2 = [0,1,2,2,3,0,4,2] 
          val2 = 2
                  
          assert Solution().removeElement(nums, val) == 2
          assert Solution().removeElement(nums2, val2) == 5
      
合并两个有序数组
  • 解法:

    • 分析输入与输出的数据,多利用指针解决

    • 给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
      
      说明:
      初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
      你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
      
      示例:
      输入:
      nums1 = [1,2,3,0,0,0], m = 3
      nums2 = [2,5,6],       n = 3
      
      输出: [1,2,2,3,5,6]
      
    • class Solution(object):
          def merge(self, nums1, m, nums2, n):
              """
              :type nums1: List[int]
              :type m: int
              :type nums2: List[int]
              :type n: int
              :rtype: None Do not return anything, modify nums1 in-place instead.
              """
              i = m-1
              j = n-1 
              tmp = i+j+1
              while j >= 0:
                  if i == -1:
                      nums1[tmp] = nums2[j]
                      j -= 1
                      tmp -= 1
                      continue
                  if nums1[i] < nums2[j]:
                      nums1[tmp] = nums2[j]
                      j -= 1
                      tmp -= 1
                  else:
                      nums1[tmp] = nums1[i]
                      i -= 1
                      tmp -= 1
                      
      # 测试             
      def test_merge():
          nums1 = [1,2,3,0,0,0]
          m = 3
          nums2 = [2,5,6]     
          n = 3
          Solution().merge(nums1, m, nums2, n)
          assert nums1 == [1,2,2,3,5,6]
      
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值