算法学习--数组(自用)

跟着大佬:代码随想录 学习算法,侵删

时间复杂度与空间复杂度是用来分析一个算法的效率的。

时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间。

一、二分查找

算法:二分查找(Binary Search)算法,也叫折半查找算法。二分查找的思想非常简单,有点类似分治的思想。二分查找针对的是一个有序的数据集合,每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。

题目:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

代码:

class Solution:

    def search(self, nums: List[int], target: int) -> int:

        left,right = 0,len(nums)-1
    
        while left<=right: # nums为左闭右闭的数组

            middle = (left+right)//2

            if nums[middle]>target:

                right = middle-1

            elif nums[middle]

二、移除数组中的元素

算法:双指针法:快指针指定新数组的元素;慢指针指定新数组元素对应的下标

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

class Solution:

    def removeElement(self, nums: List[int], val: int) -> int:

        len_nums = len(nums)-1

        #双指针法

        slow = 0

        for i in range(len_nums): #i为快指针,指向元素

            if nums[i] != val:

                nums[slow] = nums[i]

                slow=slow+1 #slow慢指针,放到循环内,指向下标

        return slow

总结:把数组中的元素与下标分开,固定下标后只要寻找符合规定的元素刚在此下标就行;我觉得该方法还可以寻找你想要的元素。不一定是移除,还可以找相同的元素。

三、有序数组的平方

题目:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

算法:双指针法:两个指针,一个指向开头,一个指向结尾

class Solution:

    def sortedSquares(self, nums: List[int]) -> List[int]:
    
    \# 暴力排序的解法时间复杂度O(n + nlog n)
    
    \# len_nums = len(nums)
    
    \# for i in range(len_nums):
    
    \# nums[i] *= nums[i]
    
    \# return sorted(nums)
    
    \# 时间复杂度O(n)解法:双指针
    
        i=0
        
        len_nums = len(nums)
        
        j = len_nums-1
        
        k = len_nums-1
        
        result = [0]*len_nums #全零数组
        
        while i<=j:
        
            l = nums[i]**2
            
            r = nums[j]**2
            
            if l

总结:要使时间复杂度小就应该不用函数,全零数组本来可以用zeros函数,但是用[0]*n实现会降低时间复杂度

四、滑动窗口

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

算法:滑动窗口明确三点:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?

窗口内:长度

窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口起始位置就要向前移动了(也就是该缩小了)。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        end,start,Sum = 0,0,0
        sumlen = len(nums)
        result = float("inf")  #定义一个最大的数,只要比nums长度长就行
        # result = sumlen+1 # 所以也可以这么定义result
        #for end in range(sumlen):
        while end= target:
                result = min(result,end-start+1) # 寻找窗口长度
                Sum = Sum - nums[start] # 首指针start移动一位后,窗口内的元素之和
                start = start+1  # 更新首指针
        return 0 if result == float("inf") else result

 总结:

暴力解法:双for循环,固定窗口的首指针,移动窗口的末尾指针

滑动窗口:for循环固定窗口的末尾指针,while循环通过移动窗口的首指针来确定窗口长度。

你可能感兴趣的:(算法学习,算法,学习,leetcode,python)