首页 > 编程语言 >代码随想录算法训练营第一天| 704. 二分查找、35.搜索插入位置、27. 移除元素、977.有序数组的平方

代码随想录算法训练营第一天| 704. 二分查找、35.搜索插入位置、27. 移除元素、977.有序数组的平方

时间:2024-11-14 18:47:55浏览次数:3  
标签:977 right return target nums int 随想录 移除 left

文档讲解:代码随想录

视频讲解:代码随想录

状态:完成4道题

一、数组理论基础

数组:连续内存空间,存储类型相同的元素集合,适合读不适合写

注意:Python里可以存储不同类型的元素,但刷题时都是按照相同元素去做的相同元素占用存储的空间大小是一样的,下一个元素的位置就确定了

数组时间复杂度:

访问:可以通过索引直接访问,时间复杂度为O(1)

搜索:需要从头开始查找,时间复杂度为O(N)

插入:找到指定元素这里的时间复杂度为O(1) ,为了保证内存空间的连续性,需要把后续的元素往后挪动,所以时间复杂度为O(N),但在最后一个元素的尾部插入,时间复杂度为O(1)

删除:找到指定元素这里的时间复杂度为O(1) ,为了保证内存空间的连续性, 需要把后续的元素往前挪动,所以时间复杂度为O(N),但删除最后一个元素,时间复杂度为O(1)。(注意:在做题时要注意数组的元素是不能删的,只能覆盖)

综上所述:Python里默认的插入、删除会操作最后一个元素,因为时间复杂度为O(1)

二、数组相关题型

704.二分查找

左闭右闭[left,right]

def search(nums, target):
    left = 0
    right = len(nums) - 1
    while left <= right:
        m = (left + right) // 2
        if nums[m] > target:
            right = m-1
        elif nums[m] < target:
            left = m+1
        else:
            return m
    return -1

左闭右开[left,right)

def search(nums, target):
    left = 0
    right = len(nums)
    while left < right:
        m = (left + right) // 2
        if nums[m] > target:
            right = m
        elif nums[m] < target:
            left = m + 1
        else:
            return m
    return -1

35.搜索插入位置

同样是二分法

左闭右闭[left,right]

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] > target:
                right = mid - 1
            else:
                left = mid + 1
        return left

左闭右开[left,right)

def searchInsert(nums, target):
    left = 0
    right = len(nums)
    while left < right:
        mid = (left + right) // 2

        if nums[mid] == target:
            return mid
        elif nums[mid] > target:
            right = mid
        else:
            left = mid + 1
    return left

27.移除元素

错误示例:当nums=[2,2] val=2时,删除第一个值后,后面的元素会移动到前面去,即索引变了,导致输出的结果为nums=[2],长度为1

因为数组是连续的只能覆盖不能直接删除

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        for i in nums:
            if val == i:
                nums.remove(i)
        return len(nums)

双指针(快慢指针)思路:

两个指针,前面一个后面一个,前面的用于搜索需要删除的值,当遇到需要删除的值时,前指针直接跳过,后面的指针不动,当遇到正常值时,两个指针都进行移动,并修改慢指针的值。最后只需输出慢指针的索引即可。

Python

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        solw,fast = 0,0
        while fast < len(nums):
            if val == nums[fast]:
                fast +=1
            else:
                nums[solw] =nums[fast]
                fast +=1
               solw +=1
        return solw

Java 

class Solution {
    public int removeElement(int[] nums, int val) {
        int n = nums.length;
        int left = 0;
        for (int right = 0; right < n; right++) {
            if (nums[right] != val) {
                nums[left] = nums[right];
                left++;
            }
        }
        return left;
    }
}

977.有序数组的平方

暴力解

def sortedSquares(nums):
    res = []
    for i in nums:
        i = i * i
        res.append(i)
    res.sort()
    return res

双指针(碰撞指针)思路:

因为是求每个数字的平方,平方后的最大值在数组两侧,靠近中间的值最小,最后按非递减顺序排序,所以使用双指针,放在数组两侧,比较平方后的大小。最后将结果按顺序放入新的数组中去。

def sortedSquares(nums):
    l = 0  # nums数组的左指针
    r = len(nums) - 1  # nums数组的右指针
    i = len(nums) - 1  # res新数组指针,从右向左开始遍历
    res = [float('inf')] * len(nums)  # 定义新数组,用来存放结果
    while l <= r:
        if nums[l] ** 2 < nums[r] ** 2:  # 左右边界进行对比,找出最大值
            res[i] = nums[r] ** 2
            r -= 1  # 右指针往左移动
        else:
            res[i] = nums[l] ** 2
            l += 1  # 左指针往右移动
        i -= 1  # 存放结果的指针需要往前平移一位
    return res

标签:977,right,return,target,nums,int,随想录,移除,left
From: https://blog.csdn.net/weixin_40702604/article/details/143743610

相关文章

  • 代码随想录算法训练营第二天| 209.长度最小的子数组、59. 螺旋矩阵 II
    文档讲解:代码随想录视频讲解:代码随想录状态:完成2道题滑动窗口滑动窗口:两个指针一前一后组成滑动窗口,并计算滑动窗口中的元素的问题适用场景:字符串匹配问题、子数组问题、定长问题滑动窗口模板:如果一个字符进入窗口,应该增加windows计数器;如果一个字符将移除窗口的......
  • 代码随想录算法训练营第三十天| 452. 用最少数量的箭引爆气球 、435. 无重叠区间 、76
    452.用最少数量的箭引爆气球思路:以前做过最大不相交子序列的题,这次也是往这根据某一端排序的思路想的,排序后如下图,只需要维护一个公共序列的右边界r就可以了,下一次判断时,只需要判断子区间的左边是否小于r。这个题有点坑的是使用Arrays排序,如果使用昨天的方法:Arra......
  • 代码随想录算法训练营 | 200.岛屿的数量
    岛屿的数量题目链接:https://leetcode.cn/problems/number-of-islands/此题目要点:dfs和bfs都可以解决此题,但是使用dfs代码会更加的简洁首先对grid进行遍历,每一个节点都进行检查,判断是否是1(陆地)如果是,则进行dfs深搜,并将所有搜到的岛屿节点全置为0,表示此块岛屿已经被搜过了,防......
  • 代码随想录算法训练营day45| 115.不同的子序列 583. 两个字符串的删除操作 72.
    学习资料:https://programmercarl.com/0115.不同的子序列.html#算法公开课动态规划系列之编辑距离问题学习记录:115.不同的子序列(当遇到相同字母时,可以选择也可以不选;刚开始没看懂;dp[i][j]是对应i-1结尾和j-1结尾,这样的目的是方便第一行和第一列初始化)点击查看代码classSolut......
  • 代码随想录:二分查找
    代码随想录:二分查找二分法标志:数组顺序排列且无重复简单的二分法,写法是左闭右闭的写法,此种情况的left可以等于right,故while里有等号。classSolution{public:intsearch(vector<int>&nums,inttarget){intleft=0;intright=nums.size()-1;......
  • 代码随想录:移除元素
    代码随想录:移除元素题目中的原地指的是不能开创新的数组。简单双指针解决问题,实际上是vector中的erase的实现原理//erase和迭代器的使用方法std::vector<int>vec={1,2,3,4,5};autoit=vec.begin()+2;//指向元素3//这所谓迭代器其实就是封装后的指针啊vec.era......
  • 代码随想录算法训练营第二十五天| leetcode491.递增子序列、leetcode46.全排列、leetc
    1leetcode491.递增子序列题目链接:491.非递减子序列-力扣(LeetCode)文章链接:代码随想录视频链接:回溯算法精讲,树层去重与树枝去重|LeetCode:491.递增子序列_哔哩哔哩_bilibili思路:用之前的方法,结果翻车了,好好看视频学新技能吧1.1视频后的思路真的没想到用set来去重,还是基......
  • 代码随想录算法训练营 | 所有可达路径
    所有可达路径文章链接:https://programmercarl.com/kamacoder/0098.所有可达路径.html#本题代码题目链接:https://kamacoder.com/problempage.php?pid=1170#include<iostream>#include<vector>usingnamespacestd;//全局路径vector<vector<int>>paths;vector<in......
  • 代码随想录算法训练营第二十四天| leetcode93.复原IP地址、 leetcode78.子集、leetcod
    1leetcode93.复原IP地址题目链接:93.复原IP地址-力扣(LeetCode)文章链接:代码随想录视频链接:回溯算法如何分割字符串并判断是合法IP?|LeetCode:93.复原IP地址_哔哩哔哩_bilibili思路:就是将这个字符串符合要求的进行一个收集,然后使用列表存储,最后使用join函数将这个列表进行连......
  • 代码随想录——二叉树17-路径总和
    这两道题目对于递归函数的返回值是不同的,这里进行总结,二叉树遍历中递归函数返回值何时有何时没有。这里总结如下三点:如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值。(这种情况就是路径总和ii)如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需......