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

【Leecode 随笔】

在这里插入图片描述

文章目录

    • 题目一:盛最多水的容器
      • 题目描述:
      • 题目分析:
      • 解题思路:
      • 示例代码:
      • 深入剖析:
    • 题目二:最长无重复字符的子串
      • 题目描述:
      • 题目分析:
      • 解题思路:
      • 示例代码:
      • 深入剖析:
    • 题目三:合并区间
      • 题目描述:
      • 题目分析:
      • 解题思路:
      • 示例代码:
      • 深入剖析:

🌈你好呀!我是 山顶风景独好
🎈欢迎踏入我的博客世界,能与您在此邂逅,真是缘分使然!😊
🌸愿您在此停留的每一刻,都沐浴在轻松愉悦的氛围中。
📖这里不仅有丰富的知识和趣味横生的内容等您来探索,更是一个自由交流的平台,期待您留下独特的思考与见解。🌟
🚀让我们一起踏上这段探索与成长的旅程,携手挖掘更多可能,共同进步!💪✨

题目一:盛最多水的容器

题目描述:

给定 n 个非负整数 a1,a2,…,an,每个数代表一个坐标点 (i, ai) 。在坐标内画 n 条垂直线,使得 i 垂直线的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴构成的容器可以容纳最多的水。

题目分析:

这是一个典型的双指针问题。我们可以使用两个指针分别指向数组的首尾,然后计算当前两个指针所构成的容器的面积。接着,我们移动指向较短线段的指针(因为容器的高度由较短的线段决定,移动较长线段的指针无法增加容器的高度,而只会减少容器的宽度),直到两个指针相遇。

解题思路:

初始化两个指针,一个指向数组的开始,另一个指向数组的末尾。
计算当前两个指针所构成的容器的面积,并更新最大面积。
移动指向较短线段的指针。
重复步骤2和3,直到两个指针相遇。
返回最大面积。

示例代码:

#include <stdio.h>  // 函数声明  
int maxArea(int* height, int heightSize);  int main() {  int height[] = {1,8,6,2,5,4,8,3,7};  int heightSize = sizeof(height) / sizeof(height[0]);  int result = maxArea(height, heightSize);  printf("Maximum area: %d\n", result);  return 0;  
}  // 计算最大容器面积的函数实现  
int maxArea(int* height, int heightSize) {  int max_area = 0;  int left = 0;  int right = heightSize - 1;  while (left < right) {  // 计算当前容器的面积  int current_area = (right - left) * ((height[left] < height[right]) ? height[left] : height[right]);  // 更新最大面积  if (current_area > max_area) {  max_area = current_area;  }  // 移动指向较短线段的指针  if (height[left] < height[right]) {  left++;  } else {  right--;  }  }  return max_area;  
}

深入剖析:

该算法的时间复杂度为O(n),因为我们只遍历了数组一次。空间复杂度为O(1),因为我们只使用了常数级别的额外空间。这种双指针的技巧在处理类似问题时非常有用,特别是当问题涉及到数组或链表的两端时。

题目二:最长无重复字符的子串

题目描述:

给定一个字符串,找出其中没有重复字符的最长子串的长度。

题目分析:

这是一个滑动窗口问题。我们可以使用两个指针来定义一个窗口,窗口内的字符都是唯一的。当遇到重复字符时,我们移动左指针来缩小窗口,直到窗口内没有重复字符为止。同时,我们需要一个哈希表来记录每个字符在窗口中的位置,以便在O(1)时间内判断字符是否重复。

解题思路:

初始化两个指针(left和right)和一个哈希表(用于记录字符的位置)。
使用right指针扩展窗口,直到遇到重复字符。
当遇到重复字符时,移动left指针缩小窗口,直到窗口内没有重复字符。
在每次移动窗口后,更新最大长度。
重复步骤2-4,直到right指针到达字符串的末尾。
返回最大长度。

示例代码:

#include <stdio.h>  
#include <string.h>  // 函数声明  
int lengthOfLongestSubstring(char * s);  int main() {  char s[] = "abcabcbb";  int result = lengthOfLongestSubstring(s);  printf("Length of longest substring without repeating characters: %d\n", result);  return 0;  
}  // 计算最长无重复字符子串长度的函数实现  
int lengthOfLongestSubstring(char * s) {  int n = strlen(s);  if (n == 0) {  return 0;  }  int max_len = 0;  int left = 0;  int right = 0;  int char_map[256] = { -1 }; // 假设输入字符为ASCII码  while (right < n) {  if (char_map[s[right]] != -1) {  // 遇到重复字符,移动左指针  left = (char_map[s[right]] + 1 > left) ? char_map[s[right]] + 1 : left;  }  // 更新字符的位置  char_map[s[right]] = right;  // 更新最大长度  max_len = (right - left + 1 > max_len) ? right - left + 1 : max_len;  // 移动右指针  right++;  }  return max_len;  
}

深入剖析:

该算法的时间复杂度为O(n),因为我们只遍历了字符串一次。空间复杂度为O(1)(如果考虑哈希表的大小为常数,因为ASCII码字符集是有限的),但实际上哈希表的大小取决于字符集的大小,对于Unicode字符集,空间复杂度会稍大一些。滑动窗口技巧在处理子串、子数组相关问题时非常有效。

题目三:合并区间

题目描述:

给出一个区间的集合,请合并所有重叠的部分。

题目分析:

这是一个排序和合并问题。首先,我们需要对区间按照起始位置进行排序。然后,我们遍历排序后的区间列表,使用一个变量来跟踪当前的合并区间。如果下一个区间的起始位置小于或等于当前合并区间的结束位置,则将它们合并;否则,将当前合并区间添加到结果列表中,并更新合并区间为下一个区间。

解题思路:

对区间按照起始位置进行排序。
初始化一个空的结果列表和一个变量来跟踪当前的合并区间。
遍历排序后的区间列表:
如果当前区间与合并区间重叠,则合并它们。
否则,将合并区间添加到结果列表中,并更新合并区间为当前区间。
将最后一个合并区间添加到结果列表中。
返回结果列表。

示例代码:

#include <stdio.h>  
#include <stdlib.h>  // 区间结构体定义  
typedef struct {  int start;  int end;  
} Interval;  // 比较函数,用于qsort排序  
int compare(const void *a, const void *b) {  Interval *intervalA = (Interval *)a;  Interval *intervalB = (Interval *)b;  return intervalA->start - intervalB->start;  
}  // 合并区间的函数声明  
Interval* merge(Interval* intervals, int intervalsSize, int* returnSize);  int main() {  Interval intervals[] = {{1, 3}, {2, 6}, {8, 10}, {15, 18}};  int intervalsSize = sizeof(intervals) / sizeof(intervals[0]);  int returnSize = 0;  Interval* result = merge(intervals, intervalsSize, &returnSize);  printf("Merged intervals:\n");  for (int i = 0; i < returnSize; i++) {  printf("[%d, %d] ", result[i].start, result[i].end);  }  printf("\n");  // 释放动态分配的内存  free(result);  return 0;  
}  // 合并区间的函数实现  
Interval* merge(Interval* intervals, int intervalsSize, int* returnSize) {  if (intervalsSize == 0) {  *returnSize = 0;  return NULL;  }  // 按照起始位置排序区间  qsort(intervals, intervalsSize, sizeof(Interval), compare);  // 动态分配结果数组的内存  Interval* merged = (Interval*)malloc(intervalsSize * sizeof(Interval));  *returnSize = 0;  // 初始化当前合并区间  Interval current = intervals[0];  for (int i = 1; i < intervalsSize; i++) {  if (intervals[i].start <= current.end) {  // 当前区间与合并区间重叠,合并它们  current.end = (intervals[i].end > current.end) ? intervals[i].end : current.end;  } else {  // 当前区间与合并区间不重叠,将合并区间添加到结果列表中,并更新合并区间  merged[*returnSize] = current;  (*returnSize)++;  current = intervals[i];  }  }  // 添加最后一个合并区间到结果列表中  merged[*returnSize] = current;  (*returnSize)++;  return merged;  
}

深入剖析:

该算法的时间复杂度为O(n log n),其中n是区间的数量,因为我们需要对区间进行排序。空间复杂度为O(n),因为我们需要动态分配一个与区间数量相等大小的结果数组。合并区间的技巧在处理类似问题时非常有用,特别是当问题涉及到重叠区间的合并、求并集等操作时。


✨ 这就是今天要分享给大家的全部内容了,我们下期再见!😊
🏠 我在CSDN等你哦!我的主页😍

http://www.xdnf.cn/news/15881.html

相关文章:

  • 使用python的读取xml文件,简单的处理成元组数组
  • 【时时三省】(C语言基础)通过指针引用字符串
  • PyCharm 高效入门指南(核心模块详解二)
  • stm32f4 dma的一些问题
  • API和SDK有何区别??
  • 跨平台猫咪键盘桌宠BongoCat v0.6.2 绿色版(附带多款皮肤包)
  • SDIO协商,枚举,CMD等概念
  • [特殊字符] Spring Boot 常用注解全解析:20 个高频注解 + 使用场景实例
  • 前端篇——番外篇 Bootstrap框架
  • (笔记+作业)第五期书生大模型实战营---L2G2000 GraphGen:训练数据合成实践
  • 前端之CSS
  • LP-MSPM0G3507学习--04GPIO控制
  • 磁悬浮转子不平衡质量的高精度控制:从原理到实战
  • 一文讲清楚React的render优化,包括shouldComponentUpdate、PureComponent和memo
  • Android音视频探索之旅 | Webrtc 1对1音视频通话核心流程分析
  • 借助AI学习开源代码git0.7之三git-init-db
  • YOLO演变史(一)
  • CSS样式中的布局、字体、响应式布局
  • CMakeLists.txt 配置文件
  • 非线性优化相关库笔记
  • 【面试题】大厂高压面经实录丨第二期
  • @Qualifier(“beanName“) 详解
  • 一个逻辑问题
  • 《设计模式之禅》笔记摘录 - 8.命令模式
  • Day06_C语言网络编程20250718mobus重点
  • gin数据解析和绑定
  • 门控线性单元GLU (Gated Linear Unit)
  • Go语言流程控制(if / for)
  • 一小时学习Redis
  • websocket案例 599足球比分