leetcode 数据结构 探索数组和字符串

1、集合:由一个或多个确定的元素所构成的整体。集合里的元素类型不一定相同,集合里的元素没有顺序。

2、数组:数组会用一些名为 索引 的数字来标识每项数据在数组中的位置。数组中的元素在内存中是连续存储的,且每个元素占用相同大小的内存。

                对于数组,计算机会在内存中申请一段 连续 的空间,并且会记下索引为 0 处的内存地址。

3、数组的操作:(1)读取元素:通过数组的索引访问数组中的元素。索引其实就是内存地址,值得一提的是,计算机可以跳跃到任意的内存地址上,

                                                       这就意味着只要计算出数组中元素的内存地址,则可以一步访问到数组中的元素,时间复杂度为 O(1)。                  

                           (2)查找元素:   计算机只会保存数组中索引为 0 处元素的内存地址,因此当计算机想要知道数组中是否包含某个元素时,只能从索引 0 处开始,

                                                      逐步向后查询。时间复杂度为 O(N),N 为数组的长度。

                           (3)插入元素:如果要将该元素插入到数组的末尾,只需要一步。即计算机通过数组的长度和位置计算出即将插入元素的内存地址,然后将该元素插入到指定位置即可。

                                                       如果要将该元素插入到数组中的其他位置,则会有所区别,这时我们首先需要为该元素所要插入的位置腾出 空间,然后进行插入操作。

                          (4)删除元素:删除元素与插入元素的操作类似,当我们删除掉数组中的某个元素后,数组中会留下 空缺 的位置,而数组中的元素在内存中是连续的,

                                                      这就使得后面的元素需对该位置进行 填补 操作。

4、字符串简介:  字符串是由零个或多个字符组成的有限序列,字符串的基本操作对象通常是字符串整体或者其子串。

数组练习题:

 
 

(3):合并区间

def merge(intervals):
    intervals.sort(key=lambda x: x[0])

    merge =[]
    for interval in intervals:
        if not merge or merge[-1][1]<interval[0]:
            merge.append(interval)
        else:
            merge[-1][1]=max(merge[-1][1],interval[1])
    return merge


"""
intervals=[[1,4],[4,5],[6,8]]
merge=[]

for 循环:
step 1: merge=[[1,4]]

step 2: merge[-1][1]=interval[0]
        merge[-1][1]=max(merge[-1][1],interval[1])=5
        merge=[[1,5]]

step3:  merge[-1][1]=5<interval[0]=6
        merge = [[1,5],[6,8]]
"""

 4、二维数组:二维数组是一种结构较为特殊的数组,只是将数组中的每个元素变成了一维数组。二维数组的本质上仍然是一个一维数组,内部的一维数组仍然从索引 0 开始,我们可以将它看作一个矩阵,并处理矩阵的相关问题。

       (4):翻转矩阵

def rotate(matrix):
    n = len(matrix)
    #新建一个N*N的辅助矩阵
    new_matrix= = [[0]*n for _ in range(n)]
    #行row
    for i in range(n):
        #列col
        for j in range(n):
            #矩阵中第i行的第j个元素,在旋转后,它出现在倒数第i列的第j个位置
            new_matrix[j][n-i-1]=matrix[i][j]
    #浅拷贝
    matrix[:] = new_matrix

       (5)矩阵清0:若M × N矩阵中某个元素为0,则将其所在的行与列清零。

x = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]

row_length = len(x)
col_length = len(x[0])

#存储需要清0行与列
row = [ ]
col = [ ]

#row
for i in range(row_length):
    #col
    for j in range(col_length):
        if x[i][j]==0:
            row.append(i)
            col.append(j)
#对row清0
for i in row:
    for j in range(col_length):
        x[i][j]=0
#对col清0
for j in col:
    for i in range(row_length):
        x[i][j]=0
        
            
print(x)

 字符串练习题:(1)字符串最长公共前缀

def f(strs):
    res =""
    for i in zip(*strs):
        if len(set(i))==1:
            res +=i[0]
        else:
             break
    return res

 6、双指针使用场景一:从两端向中间迭代数组。使用技巧:一个指针从头部开始,而另一个指针从尾部开始。

(1)翻转数组

def f(s):
    i = 0
    j = len(s)-1
    while i<j:
        s[i],s[j] = s[j],s[i]
        i +=1
        j -=1
    return s
    
s = ['l', 'e', 'e', 't', 'c', 'o', 'd', 'e']
print(f(s))

 (2)给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数.函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。且index不从0开始

def f(nums,target):
    n = len(nums)
    i = 0
    j = n-1
    while i<j:
        sum = nums[i]+nums[j]
        if sum==target:
            return [i+1,j+1]
        elif sum<target:
            i +1
        else:
            j -=1

nums = [2, 7, 11, 15]
target =9
print(f(nums,target))

 :7、双指针使用场景二:快慢指针。确定两个指针的移动策略,有时可能需要在使用双指针技巧之前对数组进行排序,也可能需要运用贪心法则来决定你的运动策略

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

#快慢指针移动策略:当快指针指向的值不等与给定值时,满指针移动。
def removeElement(nums,val):
    n=len(nums)
    slow = 0
    for fast in range(n):
        if nums[fast]!=val:
            nums[slow]=nums[fast]
            slow +=1
    return slow

     (2)给定一个二进制数组, 计算其中最大连续1的个数

def f(nums):
    if 1 not in nums:
        return 0
    else:
        n = len(nums)
        slow = 0
        x = []
        for fast in range(n):
            if nums[fast]==1:
                slow +=1
                x.append(slow)
            else:
                slow = 0
        return max(x)

  (3)给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度。如果不存在符合条件的连续子数组,返回 0

  

def f(nums,s):
    n = len(nums)
    #初始化左指针
    left = 0
    #初始化最小长度:正无穷。即数组中所有元素累计和小于s
    res = float("inf")
    #初始化数组中元素累和
    temp = 0
    #右指针 r 
    for right in range(n):
        temp +=nums[right]
        #进入循环的条件:元素累和>=s
        while (temp>=s):
            #记录此时最小长度
            res  = min(res, right-left+1)#right-left+1代表左指针到右指针的长度
            temp -=nums[left]#滑动窗口的原则:先进先出。当元素累和超过s时,从左侧吐掉元素。
            left +=1
    if res !=float("inf"):
        return res
    else:
        return 0
            

nums =[2,3,1,2,4,3]
s = 7
print(f(nums,s))
原文地址:https://www.cnblogs.com/yijierui/p/13162553.html