代码随想录算法训练营day01_ 704. 二分查找、27. 移除元素

算法性能的评估

时间复杂度和空间复杂度是衡量算法效率的两个重要指标。时间复杂度描述了算法运行所需的时间量,而空间复杂度描述了算法运行时所需的内存空间。
1.时间复杂度
可以用大O符号来表示,例如O(n)表示算法的时间复杂度与输入规模n成正比。以下是一些常见的时间复杂度:

  • O(1) 常数时间复杂度:无论输入规模如何,算法的运行时间都是固定的。例如,访问数组中的一个元素。
  • O(log n) 对数时间复杂度:算法的运行时间随着输入规模的增加而增加,但增长速度很慢。例如,二分查找算法。
  • O(n) 线性时间复杂度:算法的运行时间与输入规模成正比。例如,遍历数组中的所有元素。
  • O(n log n) 线性对数时间复杂度:算法的运行时间随着输入规模的增加而增加,但增长速度比线性更快。例如,快速排序算法。
  • O(n^2) 平方时间复杂度:算法的运行时间随着输入规模的增加而增加,增长速度很快。例如,嵌套循环遍历二维数组。

2.空间复杂度
也可以用大O符号来表示。例如,O(1)表示算法所需的额外内存量与输入规模无关,O(n)表示算法所需的额外内存量与输入规模成正比。以下是一些常见的空间复杂度:

  • O(1) 常数空间复杂度:算法所需的额外内存量固定,与输入规模无关。例如,交换两个变量的值。
  • O(n) 线性空间复杂度:算法所需的额外内存量与输入规模成正比。例如,复制一个数组。
  • O(n^2) 平方空间复杂度:算法所需的额外内存量与输入规模的平方成正比。例如,创建一个二维数组。

704.二分查找

题目链接
1.使用二分查找的前提是数组升序
2.二分查找的时间复杂度为O(logn),空间复杂度为O(1)
3.二分查找最主要的问题在于区间开闭的选择

区间的选择取决去right的取值,如果right = nums.length - 1,我们知道数组的最后一个元素下标正好为nums.right - 1,所以为左闭右闭区间,这个时候再来判断while条件里的<还是<=,我们假设为<,那么循环的结束条件为left == right,但由于left == right(举例为[2, 2],)是对于左闭右闭区间是成立的,所以应该为<=符号,<=的结束条件为left == right + 1;
左闭右闭区间

class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] > target) {
                right = mid - 1;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] == target) {
                return mid;
            }
        }
        return -1;
    }
}

同理,当right = nums.length,nums.length是取不到的,所以使用<,结束条件为left == right即可
左闭右开区间

class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] > target) {
                right = mid;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else if (nums[mid] == target) {
                return mid;
            }
        }
        return -1;
    }
}

27. 移除元素

题目链接
1.原地移除指定的元素,只能使用O(1)的空间复杂度

方法一:暴力

思路: 遍历数组,找到需要移除的元素,就把该元素后的所有元素向前移动,来实现覆盖的效果.
时间复杂度:O(n2)
空间复杂度:O(1)

class Solution {
    public int removeElement(int[] nums, int val) {
        int len = nums.length;
        for (int i = 0; i < len; i++) {
            // 发现目标元素就将数组整体向前移动一位
            if (nums[i] == val) {
                for (int j = i + 1; j < len; j++) {
                    // 用目标元素的后一位元素去覆盖目标元素
                    nums[j - 1] = nums[j];
                }
                // i以后的数值都向前移动了一位,所以i也向前移动一位
                i--;
                // 数组前移后,数组大小减一
                len--;
            }
        }
        return len;
    }
}

方法二:快慢指针

思路:使用快慢指针,核心思路就是,慢指针找到一个需要移除的元素后就不移动了,等待快指针找到不需要移除的元素,然后进行替换,就实现了原地移除指定元素的效果
时间复杂度:O(n)
空间复杂度O(1)

class Solution {
    public int removeElement(int[] nums, int val) {
        int slow = 0;
        for (int fast = 0; fast < nums.length; fast++) {
            if (nums[fast] != val) {
                nums[slow++] = nums[fast];
            }
        }
        return slow;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小C卷Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值