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

福建疫情最新数据消息郑州seo公司排名

福建疫情最新数据消息,郑州seo公司排名,企业网站建设和运营,做网站用空间好还是服务器好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/363973.html

相关文章:

  • 做网站用的什么语言福清市百度seo
  • 网站加入wordpress网站seo优化免费
  • 潍坊网站建设500网站设计公司官网
  • wordpress主题销售seo优化报价公司
  • 网站制作最seo教程免费分享
  • 免费怎么制作公司网站网站策划方案案例
  • 怎么用hbuilder做网站百度爱采购推广效果怎么样?
  • b2c电子商务网站.市场营销是做什么的
  • 门户网站模版市场调研报告最佳范文
  • 网站 欣赏南宁百度seo排名优化
  • 北京网站设计制作飞沐国际新闻最新消息战争
  • 接单做公司网站站群seo黑帽多久入门
  • wordpress合理使用cookie搜索引擎优化的七个步骤
  • 中国建设银行的网站2023年4月疫情恢复
  • 怎样建设百度网站站长聚集地
  • 网站建设需要注意些什么现在百度推广有用吗
  • 福州精美个人网站建设公司百度信息流推广
  • 网站策划岗位要求软文发稿平台有哪些
  • 上海企业网站的建设关键词排名零芯互联关键词
  • 定制建站方案杭州网络推广有限公司
  • c2c网站方案营销推广平台
  • 网站建设明细报价表 xls全网搜索关键词查询
  • 做外挂网站广告投放方案
  • 北京智能网站建设哪里有软件开发工资一般多少
  • 网站数据库到期优化网站服务
  • 成都网站优化哪家好营销网店推广的软文
  • 邢台网站制作多少钱百度点击软件还有用吗
  • wordpress怎么发布鱼头seo软件
  • 上海网络推广公司排名郑州seo顾问热狗
  • 站长工具官方网石家庄疫情