Leetcode 76. 最小覆盖子串和Leetcode 34. 在排序数组中查找元素的第一个和最后一个位置

文章目录

  • Leetcode 76. 最小覆盖子串
    • 题目描述
    • C语言题解和思路
      • 解题思路
  • Leetcode 34. 在排序数组中查找元素的第一个和最后一个位置
    • 题目描述
    • C语言题解和思路
      • 解题思路


Leetcode 76. 最小覆盖子串

题目描述

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

注意:

对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。

示例 1:

输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”
解释:最小覆盖子串 “BANC” 包含来自字符串 t 的 ‘A’、‘B’ 和 ‘C’。

示例 2:

输入:s = “a”, t = “a”
输出:“a”
解释:整个字符串 s 是最小覆盖子串。

示例 3:

输入: s = “a”, t = “aa”
输出: “”
解释: t 中两个字符 ‘a’ 均应包含在 s 的子串中,
因此没有符合条件的子字符串,返回空字符串。

提示:

  • m == s.length
  • n == t.length
  • 1 <= m, n <= 10^5
  • s 和 t 由英文字母组成

进阶: 你能设计一个在 o(m+n) 时间内解决此问题的算法吗?

C语言题解和思路

char* minWindow(char* s, char* t) {
    int sl = strlen(s), tl = strlen(t), left, right, count = sl + 1, start = 0;
    if(tl > sl)
    {
        return "";
    }
    int hash[256] = {0};
    for(int i = 0; i < tl; i++)
    {
        hash[t[i]]++;
    }
    for(left = 0, right = 0; right < sl; right++)
    {
        if(hash[s[right]]-- > 0)
        {
            tl--;
        }
        while(tl == 0)
        {
            if(count > right - left + 1)
            {
                count = right - left + 1;
                start = left;
            }
            if(++hash[s[left]] > 0)
            {
                tl++;
            }
            left++;
        }
    }
    if(count != sl + 1)
    {
        char *ret = (char *)malloc(sizeof(char) * (count + 1));
        memcpy(ret, s + start, count);
        ret[count] = '\0';
        return ret;
    }
    return "";
}

解题思路

哈希表 + 滑动窗口

首先判断字符串 t 的长度和字符串 s 的长度,如果 t 长于 s ,说明字符串 s 不可能存在容纳 t 的子串,直接返回空。

创建一个哈希表并初始化为 0 ,然后循环字符串 t ,用哈希表记录 t 的字母的种类和数量。

将左右指针初始化为 0 ,将记录最小子串的长度的变量 count 初始化为字符串 s 的长度加一。

通过滑动窗口遍历字符串 s , right 每将一个新元素纳入窗口,都先通过哈希表判断它是否在字符串 t 中出现过,如果出现过,则使字符串 t 的长度减一。当窗口将所有的字符串 t 中出现的元素都包含在内,也就是字符串 t 的长度归 0 时,开始循环判断窗口的左边界,同时 count 不断判断左右边界的距离,也就是最小覆盖子串的长度,并记录下此时左边界的位置,循环至窗口中无法覆盖所有的字符串 t 的元素为止。

循环结束后,判断 count 是否发生变化,如果它不再比字符串 s 还长,说明字符串 s 中存在满足条件的子串,此时将该子串通过memcpy函数、记录下来的左边界的值、最小的长度,将这段字符串复制到另一个字符数组当中,在新的字符串后添加上 ‘\0’ 后返回该字符串。

如果 count 没有发生改变,返回空。

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

题目描述

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]。

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2:

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例 3:

输入:nums = [], target = 0
输出:[-1,-1]

提示:

  • 0 <= nums.length <= 105
  • -10 ^9 <= nums[i] <= 10 ^9
  • nums 是一个非递减数组
  • -10 ^9 <= target <= 10 ^9

C语言题解和思路

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* searchRange(int* nums, int numsSize, int target, int* returnSize) {
    int *ret = (int *)malloc(sizeof(int) * 2);
    ret[0] = -1;
    ret[1] = -1;
    *returnSize = 2;
    if(numsSize == 0 || nums[0] > target || nums[numsSize - 1] < target )
    {
        return ret;
    }
    int left = 0, right = numsSize - 1, mid;
    while(left <= right)
    {
        mid = (left + right) / 2;
        if(nums[mid] == target)
        {
            left = mid;
            right = mid;
            while(left - 1 >= 0 && nums[left - 1] == target)
            {
                left--;
            }
            while(right + 1 < numsSize && nums[right + 1] == target)
            {
                right++;
            }
            ret[0] = left;
            ret[1] = right;
            return ret;
        }
        else if(nums[mid] > target)
        {
            right = mid - 1;
        }
        else if(nums[mid] < target)
        {
            left = mid + 1;
        }
    }
    return ret;
}

解题思路

二分查找

首先将返回的数组 ret 初始化为-1,因为数组为有序数组,先判断数组个数是否为 0 ,数组的第一个元素是否大于 target 值,数组的最后一个元素是否小于 target 值,如果以上条件满足其一,直接返回数组 ret 。

进入循环,对数组进行二分查找,如果找到满足条件的值,将下标赋给左右指针,分别循环左右指针寻找数组中值等于 target 值的左右边界的下标,将左右下标传给数组 ret ,返回 ret 。

当二分查找完后数组仍没返回任何值,说明数组中不存在值等于 target 的元素,返回值为-1的数组 ret 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/555492.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何辨别:DNS污染or DNS劫持?

DNS劫持和DNS污染的情况在互联网中并不少见&#xff0c;到底是出现了DNS污染还是DNS劫持。什么是DNS污染&#xff1f;什么是DNS劫持&#xff1f;我们该如何辨别DNS污染和DNS劫持&#xff1f; DNS劫持&#xff1a; DNS 劫持是指恶意攻击者通过非法手段篡改了网络中的 DNS 服务…

HTML快速入门

HTML简介 HTML&#xff08;超文本标记语言&#xff09;是一种用于创建网页和Web应用程序的标记语言。它由一系列标签组成&#xff0c;每个标签通过尖括号来定义&#xff0c;并用于标记文本、图像、链接和其他内容。HTML标签描述了网页中的信息结构和布局&#xff0c;并定义了文…

[MySQL数据库] 索引与事务

1. 索引 1.1 概念 索引是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针.可以对表中的一列或多列创建索引,并指定索引的类型&#xff0c;各类索引有各自的数据结构实现. 1.2 作用 数据库中的表、数据、索引之间的关系&#xff0c;类似于书架上的图书、书籍…

【Redis】面试题汇总

Redis什么是Redis、使用场景有哪些Redis 为什么这么快&#xff1f;Redis 数据类型及使用场景五种常见的 Redis 数据类型是怎么实现&#xff1f;Redis是单线程吗Redis 采用单线程为什么还这么快&#xff1f;Redis 如何实现数据不丢失&#xff1f;Redis 如何实现服务高可用&#…

【复习笔记】FreeRTOS(六) 队列操作

本文是FreeRTOS复习笔记的第六节&#xff0c;队列操作。 上一篇文章&#xff1a; 【复习笔记】FreeRTOS(五)时间片调度 文章目录 1.队列操作1.1.队列操作过程1.2.队列操作常用的API函数 二、实验设计三、测试例程四、实验效果 1.队列操作 队列是为了任务与任务、任务与中断之间…

极狐GitLab x LigaAI,AI 时代研发提效新范式

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 近日&#xff0c;极狐GitLab 和 LigaAI 宣布合作&#xff0c;双…

分布式锁设计

一、为什么需要分布式锁 1.1 单体项目同步实现 在单进程&#xff08;启动一个jvm&#xff09;的系统中&#xff0c;当存在多个线程可以同时改变某个变量&#xff08;可变共享变量&#xff09;时&#xff0c;就需要对变量或代码块做同步&#xff0c;使其在修改这种变量时能够线…

vue2中props属性设置一个对象或数组的默认值

在Vue.js中&#xff0c;如果您想要为一个props属性设置一个对象或数组的默认值&#xff0c;您应该使用一个函数来返回这个默认值。这是因为对象和数组是引用类型&#xff0c;直接将它们作为默认值可能会导致预设的默认值被所有实例共享&#xff0c;这不是我们想要的结果。 下面…

zabbix 自定义模板,邮件报警,代理服务器,自动发现与自动添加及snmp

目录 一. 自定义监控内容 1. 在客户端创建自定义 key 2. 在 web 页面创建自定义监控项模块 2.1 创建模板 2.2 创建应用集 2.3 创建监控项 2.4 创建触发器 2.5 创建图形 2.6 将主机与模板关联起来 登录测试 2.7 设置邮件报警 测试邮件报警 3. nginx 服务状况的检测…

Vue中SourceMap的使用方法详解

目录 一、概述 二、使用方法 三、生成SourceMap 四、优化 五、结语 一、概述 Vue.js是一套构建用户界面的渐进式框架&#xff0c;通过HTML模板或者直接写render函数可以快速开发单页应用。在开发过程中&#xff0c;很多时候我们需要调试代码&#xff0c;追踪错误。Vue官方…

Linux:调试器 - gdb

Linux&#xff1a;调试器 - gdb gbd基本概念gbd调试浏览断点运行变量 gbd基本概念 GDB (GNU Debugger) 是一个强大的命令行调试工具,用于调试各种编程语言(如C、C、Java、Python等)编写的程序。使用 gdb可以帮助开发人员更快地定位和修复程序中的缺陷,提高代码质量和开发效率。…

Python介绍(未完)

文章目录 Python 背景知识Python 是谁创造的&#xff1f;Python 可以用来干什么&#xff1f;Python 的优缺点 搭建 Python 环境安装 Python搭建 PyCharm 环境新工具到手&#xff0c;赶紧试试中文设置第一个Python程序 Python基础语法基础语法&#xff08;1&#xff09;常量和表…

Error : java 错误 : 不支持发行版本5 ( 完美解决)

解决方案 1. 原因 idea的默认配置JDK版本与当前项目所需版本不一样 方案一&#xff08;每一个项目可能都要配置一遍&#xff09; Ctrlshitalts 打开项目结构&#xff0c;设置项目所需的JDK版本&#xff0c;本项目需要JDK8 Modules的JDK版本为5&#xff0c;这时就会报Error …

最大公约数和最小公倍数(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//实现最大公约数函数&#xff1b; int max(int x, int y) {//初始化变量值&#xff1b;int judge 1;//运算&#xff1b;judge x %…

Ubuntu 23.10.1 nginx源码安装

注&#xff1a;以下所有命令均在root管理员模式下&#xff0c;若不是&#xff0c;请在所有命令前加sudo 1、安装依赖库 1.1、安装gcc g的依赖库 apt-get install build-essential apt-get install libtool1.2、安装pcre依赖库 apt-get update apt-get install libpcre3 lib…

剑指Offer题目笔记33(并查集)

面试题116&#xff1a; 解决方案&#xff1a; ​ 一个班级可以包含一个或多个朋友圈&#xff0c;对应的图中可能包含一个或多个子图&#xff0c;每个朋友圈对应一个子图。因此&#xff0c;这个问题可以转化为如何求图中子图的数目。图的搜索算法可以用来计算图中子图的数目。扫…

企业Linux特殊权限位/为什么会存在SUID?/企业环境测试(原理剖析)-4989字解析

企业高薪思维&#xff1a; 坚持很难&#xff0c;优秀的人才是少数&#xff0c;很重要 坚持不下去&#xff0c;问自己想要什么&#xff1f; 问问自己想要好的生活状态&#xff1f;问自己有背景吗&#xff1f;你学历是亮点吗&#xff1f;有钱没&#xff0c;你也就是一般家庭&…

selenium 下载文件取消安全下载的方法

问题描述 我要从一个网站上下载文件&#xff0c;谷歌浏览器总是自动阻止下载&#xff0c;并询问我是否保留。 可是&#xff0c;我想要的是不要询问&#xff0c;默认下载即可。 运行环境 OS: macOSselenium: 4.19.0python: 3.10.11Chrome: 124.0.6367.62selenium chromedrive…

工会排队模式:创新营销的双赢之道

工会排队模式全面解读 在当今数字化营销的大潮中&#xff0c;促销方式层出不穷&#xff0c;但能真正抓住消费者眼球并带来双方共赢的模式并不多见。而工会排队模式便是在这样的背景下崭露头角&#xff0c;它巧妙地融合了工会积分、奖金池与排队机制&#xff0c;为消费者与商家…

linux进阶篇:重定向和管道操作

Linux中的重定向和管道操作 llinux中的三种IO设备&#xff1a; 标准输入&#xff08;STDIN&#xff09;,文件描述符号为&#xff1a;0&#xff0c;默认从键盘获取输入 标准输出&#xff08;STDOUT&#xff09;,文件描述符号位&#xff1a;1&#xff0c;默认输出到显示终端 标准…
最新文章