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

【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.dtcms.com/a/285757.html

相关文章:

  • 系统分析师-计算机系统-指令系统多处理机系统
  • 【案例教程】基于现代R语言【Tidyverse、Tidymodel】的机器学习方法与案例分析实践技术应用
  • 如何将 iPhone 备份到笔记本电脑?
  • mac mlx大模型框架的安装和使用
  • Web前端入门:JavaScript async await 的异步任务进化之路
  • 深入解析文本分类技术全景:从特征提取到深度学习架构
  • 【项目】MCP+GraphRAG搭建检索增强智能体
  • -lstdc++与-static-libstdc++的用法和差异
  • 谈进程间通信
  • 从Hyperliquid到AILiquid:一场从极致性能到策略智能的迭代
  • 硅和锗二极管的主要区别
  • 参会邀请!2025世界人工智能大会合合信息技术交流日报名启动!
  • 深入理解 Linux 进程间通信
  • Linux——库的制作与原理
  • Linux 信号与中断 详解
  • ali linux 上安装swagger-codegen
  • Windows发现可疑的svchost程序
  • 深度理解 KVM:Linux 内核系统学习的重要角度
  • 【Linux】环境基础与开发工具的使用
  • Linux中的LVS集群技术
  • MySQL的基本操作及相关python代码
  • 基于极空间NAS+GL-MT6000路由器+Tailscale的零配置安全穿透方案
  • 云原生 DevOps 实战之Jenkins+Gitee+Harbor+Kubernetes 构建自动化部署体系
  • 小白学Python,网络爬虫篇(2)——selenium库
  • 图机器学习(13)——图相似性检测
  • 信息学奥赛一本通 1575:【例 1】二叉苹果树 | 洛谷 P2015 二叉苹果树
  • 短视频矩阵系统哪家好?全面解析与推荐
  • 香港服务器SSH安全加固方案与密钥认证实践
  • Flutter权限管理终极指南:实现优雅的Android 48小时授权策略
  • GLU 变种:ReGLU 、 GEGLU 、 SwiGLU