当前位置: 首页 > wzjs >正文

网站访问量查询工具查看今日头条

网站访问量查询工具,查看今日头条,做轻时尚的网站,北京建设委官方网站34. 在排序数组中查找元素的第一个和最后一个位置 题目 思路 本题的核心思路是二分查找。 解题过程 问题分析:在一个升序排列的数组中查找一个目标值 target 的起始和结束位置。这是一个典型的二分查找应用场景。核心转换:题目要求找到 target 的第一个…

34. 在排序数组中查找元素的第一个和最后一个位置

题目

LeetCode Problem 34

思路

本题的核心思路是二分查找

解题过程

  1. 问题分析:在一个升序排列的数组中查找一个目标值 target 的起始和结束位置。这是一个典型的二分查找应用场景。
  2. 核心转换:题目要求找到 target 的第一个位置和最后一个位置。这可以转换为两个子问题:
    • 找到第一个 大于等于 target 的元素的下标(记为 left_bound)。
    • 找到第一个 大于 target 的元素的下标,然后将这个下标减 1,就得到 target 的最后一个位置(记为 right_bound)。这等价于找到第一个 大于等于 target + 1 的元素的下标,然后减 1。
  3. 实现lower_bound函数:我们可以实现一个通用的二分查找函数 lower_bound(nums, k),用于查找数组 nums 中第一个大于等于 k 的元素的下标。
    • 初始化指针 left = 0, right = nums.length - 1
    • 循环条件 while (left <= right)
    • 计算中间位置 mid = left + (right - left) / 2
    • 如果 nums[mid] < k,说明目标值 k(或第一个大于等于 k 的元素)一定在 mid 的右侧,更新 left = mid + 1
    • 如果 nums[mid] >= k,说明 mid 可能是第一个大于等于 k 的元素,或者目标在 mid 的左侧。因此,我们需要继续在左半部分(包括 mid 本身)查找,更新 right = mid - 1
    • 循环结束后,left 指针指向的位置就是第一个大于等于 k 的元素的下标。如果数组中所有元素都小于 kleft 将会等于 nums.length
  4. 求解
    • 调用 lower_bound(nums, target) 得到 left_index
    • 检查 left_index:如果 left_index 等于数组长度 nums.length 或者 nums[left_index] 不等于 target,说明数组中不存在 target,直接返回 [-1, -1]
    • 调用 lower_bound(nums, target + 1) 得到 right_index_plus_one
    • target 的最后一个位置是 right_index_plus_one - 1
    • 返回 [left_index, right_index_plus_one - 1]

复杂度

  • 时间复杂度: O(log n) - 两次二分查找。
  • 空间复杂度: O(1) - 只使用了常数级别的额外空间。

Code

class Solution {public int[] searchRange(int[] nums, int target) {// 查找第一个大于等于 target 的位置int leftIdx = lower_bound(nums, target);// 检查 leftIdx 是否越界 或 nums[leftIdx] != target// 如果是,说明 target 不存在if (leftIdx == nums.length || nums[leftIdx] != target) {return new int[] {-1, -1};}// 查找第一个大于等于 target + 1 的位置// 这个位置的前一个位置就是 target 的最后一个位置int rightIdx = lower_bound(nums, target + 1) - 1;return new int[] {leftIdx, rightIdx};}// 查找数组中第一个大于等于 k 的元素的下标private int lower_bound(int[] nums, int k) {int left = 0, right = nums.length - 1;while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] < k) {// [mid+1, right]left = mid + 1;} else { // nums[mid] >= k// [left, mid-1]right = mid - 1;}}// 循环结束后,left 就是第一个 >= k 的元素的下标return left;}
}

35. 搜索插入位置

题目

LeetCode Problem 35

思路

同样使用二分查找

解题过程

  1. 问题分析:在一个 无重复元素 的有序数组中,查找目标值 target。如果找到,返回其下标;如果找不到,返回它应该插入的位置的下标,以保持数组有序。
  2. 核心思想:这个问题本质上就是查找数组中第一个 大于等于 target 的元素的下标。
    • 如果数组中存在 target,那么第一个大于等于 target 的元素就是 target 本身,其下标即为所求。
    • 如果数组中不存在 target,那么第一个大于等于 target 的元素的位置,就是 target 应该插入的位置。
  3. 实现:可以直接复用上一题中的 lower_bound 查找逻辑。
    • 初始化 left = 0, right = nums.length - 1
    • 循环 while (left <= right)
    • 计算 mid
    • 如果 nums[mid] < target,目标在右侧,left = mid + 1
    • 如果 nums[mid] >= target,目标在 mid 或其左侧,right = mid - 1
    • 循环结束后,left 就是第一个大于等于 target 的元素的下标。
  4. 边界情况处理
    • 如果数组中所有元素都小于 target,循环过程中 left 会一直右移,最终 left 变为 nums.length,这正好是 target 应该插入的位置。
    • 如果数组中所有元素都大于 target,循环过程中 right 会一直左移,最终 left 保持为 0,这也是 target 应该插入的位置。
    • 因此,该二分查找的返回值 left 直接就是答案。

复杂度

  • 时间复杂度: O(log n) - 一次二分查找。
  • 空间复杂度: O(1) - 只使用了常数级别的额外空间。

Code

class Solution {public int searchInsert(int[] nums, int target) {int left = 0, right = nums.length - 1;while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid + 1; // 继续在右区间 [mid+1, right] 查找} else { // nums[mid] >= targetright = mid - 1; // 继续在左区间 [left, mid-1] 查找}}// 循环结束后,left 指向第一个大于等于 target 的元素下标// 或者,如果 target 大于所有元素,left 指向 nums.lengthreturn left;}
}

92. 反转链表 II (复习)

题目

LeetCode Problem 92

复习心得

今天是第二次做这道题。核心思路仍然是找到 left 位置的前一个节点 prev,然后使用头插法,在 leftright 区间内,依次将 cur 后面的节点 curNext 移动到 prev 的后面(也就是反转区间的头部)。

while 循环里,关键在于理解节点连接的变化:

  1. 保存 cur 的下一个节点:ListNode curNext = cur.next;
  2. cur 跳过 curNext,指向 curNext 的下一个节点:cur.next = curNext.next;
  3. curNext 插入到反转区间的头部,也就是 prev 的后面:curNext.next = prev.next;
  4. prev 指向新的头部 curNextprev.next = curNext;

今天在写的时候,容易混淆的是步骤 3 和 4。一开始容易错误地写成 curNext.next = cur,这是不对的,因为 cur 是在移动的,只有在循环开始前 prev.next 才指向反转区间的第一个节点。正确的做法是始终将 curNext 插入到 prev.next 所指向的位置。

详细题解可以参考之前的笔记:每日算法-250328

Code

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseBetween(ListNode head, int left, int right) {// 使用虚拟头节点简化边界处理(left=1 的情况)ListNode dummy = new ListNode(0);dummy.next = head;// 1. 找到 left 位置的前一个节点 prevListNode prev = dummy;for (int i = 1; i < left; i++) {prev = prev.next;}// prev.next 就是反转区间的第一个节点,记为 curListNode cur = prev.next;// 2. 执行头插法反转 left 到 right 区间的节点// 总共需要执行 right - left 次头插操作for (int i = left; i < right; i++) {// 获取 cur 的下一个节点,它将是下一个要移动到头部的节点ListNode nodeToMove = cur.next;// cur 跳过 nodeToMovecur.next = nodeToMove.next;// 将 nodeToMove 插入到 prev 的后面nodeToMove.next = prev.next;prev.next = nodeToMove;}return dummy.next;}
}
http://www.dtcms.com/wzjs/429007.html

相关文章:

  • 中型网站开发周期西安seo王尘宇
  • 武汉招聘网站制作什么平台打广告比较好免费的
  • 南昌专业做网站的如何做一个自己的网站呢
  • 网页设计与网站建设完全学习手册pdf软文经典案例
  • 宝塔怎么做两个网站的解析榆林百度seo
  • 东莞阳光网站建设成效如何制作小程序
  • 建设银行河北分行官网招聘网站网站关键词排名查询工具
  • 政协网站 是政协信息化建设网站互联网推广
  • 做淘宝链接的网站seo推广方案怎么做
  • 西安电商网站建设百度搜索指数是怎么计算的
  • 企业网站建设一条google官网下载安装
  • 徐州网站建设xlec百度关键词竞价
  • 北京网站怎么做百色seo关键词优化公司
  • ppt图标网站链接怎么做百度在线使用
  • gta5房地产网站建设中中央下令全国各地核酸检测
  • 美食网站开发背景网络营销组织的概念
  • 平台搭建与拆除流程北京seo网站设计
  • 可以进入外国网站的浏览器网推资源渠道
  • 做多肽的都有哪些网站百度正版下载恢复百度
  • 网站建设有什么费用产品经理培训哪个机构好
  • 学做电商的网站seo范畴有哪些
  • 孟州网站国产长尾关键词拘挖掘
  • 网站地图怎么做_百度云搜索引擎网站
  • 做毕业设计免费网站建设怎么优化一个网站关键词
  • 做竞猜网站犯法吗长沙百度seo代理
  • app网站建设制作seo排名点击首页
  • 西安网站建设是什么bt磁力搜索引擎
  • 网站上线需要怎么做seo优化搜索推广
  • 西安网站建设服务商vivo应用商店
  • 外卖网站开发背景外贸网站推广平台有哪些