首页 > 其他分享 >2663. 字典序最小的美丽字符串

2663. 字典序最小的美丽字符串

时间:2024-06-22 23:29:46浏览次数:13  
标签:return int len char 2663 字符串 字典 result

题目

如果一个字符串满足以下条件,则称其为美丽字符串:

  • 它由英语小写字母表的前 k 个字母组成。
  • 它不包含任何长度为 2 或更长的回文子字符串。

给你一个长度为 n 的美丽字符串 s 和一个正整数 k

请你找出并返回一个长度为 n 的美丽字符串,该字符串还满足:在字典序大于 s 的所有美丽字符串中字典序最小。如果不存在这样的字符串,则返回一个空字符串。

对于长度相同的两个字符串 ab ,如果字符串 a 在与字符串 b 不同的第一个位置上的字符字典序更大,则字符串 a 的字典序大于字符串 b

例如,“abcd” 的字典序比 “abcc” 更大,因为在不同的第一个位置(第四个字符)上 d 的字典序大于 c

示例 1:

输入:s = “abcz”, k = 26
输出:“abda”
解释:字符串 “abda” 既是美丽字符串,又满足字典序大于 “abcz”。可以证明不存在字符串同时满足字典序大于 “abcz”、美丽字符串、字典序小于 “abda” 这三个条件。

示例 2:

输入:s = “dc”, k = 4
输出:“”
解释:可以证明,不存在既是美丽字符串,又字典序大于 “dc” 的字符串。

提示:

  • 1 <= n == s.length <= 10^5
  • 4 <= k <= 26
  • s 是一个美丽字符串

代码

完整代码

#include <stdbool.h>
#include <string.h>
#include <stdlib.h>

bool isBeauty(char* s, int len) {
    if (len == 0 || len == 1) {
        return false;
    } else if (len == 2) {
        return s[0] != s[1];
    }
    for (int i = 0; i + 2 < len; i++) {
        if (s[i] == s[i + 1] || s[i] == s[i + 2] || s[i + 1] == s[i + 2]) {
            return false;
        }
    }
    return true;
}

char* smallestBeautifulString(char* s, int k) {
    char alphaBet[] = "abcdefghijklmnopqrstuvwxyz";
    int len = strlen(s);
    if (len == 1 && s[0] < alphaBet[k-1]) {
        s[0]++;
        return s;
    }
    char* result = (char*)calloc(len + 1, sizeof(char));
    strcpy(result, s);

    while (1) {
        for (int i = len - 1; i >= 0; i--) {
            if (result[i] < alphaBet[k - 1]) {
                result[i]++;
                for (int j = i + 1; j < len; j++) {
                    result[j] = alphaBet[0];
                }
                if (isBeauty(result, len)) {
                    return result;
                }
                break;
            } else {
                result[i] = alphaBet[0]; 
            }
        }

        bool allMax = true;
        for (int i = 0; i < len; i++) {
            if (result[i] != alphaBet[k - 1]) {
                allMax = false;
                break;
            }
        }
        if (allMax) {
            break;
        }
    }

    free(result);
    return strdup("");
}

思路分析

这套代码用了模拟的方法。

  • 首先初始化一个结果字符串 result,它的初始值为输入字符串 s
  • 从字符串的末尾开始,逐个字符尝试将其增加。
  • 每次增加一个字符后,检查整个字符串是否仍然是美丽字符串。
  • 如果是美丽字符串,则返回该字符串。
  • 如果所有字符都尝试过最大值,且仍然找不到合适的字符串,则返回空字符串。

拆解分析

  1. isBeauty函数
bool isBeauty(char* s, int len) {
    if (len == 0 || len == 1) {
        return false;
    } else if (len == 2) {
        return s[0] != s[1];
    }
    for (int i = 0; i + 2 < len; i++) {
        if (s[i] == s[i + 1] || s[i] == s[i + 2] || s[i + 1] == s[i + 2]) {
            return false;
        }
    }
    return true;
}

isBeauty函数用于检查一个字符串是否为美丽字符串。具体实现为判断字符串中是否存在长度为2或更长的回文子字符串。

  1. 初始检查与内存分配
char* smallestBeautifulString(char* s, int k) {
    char alphaBet[] = "abcdefghijklmnopqrstuvwxyz";
    int len = strlen(s);
    if (len == 1 && s[0] < alphaBet[k-1]) {
        s[0]++;
        return s;
    }
    char* result = (char*)calloc(len + 1, sizeof(char));
    strcpy(result, s);

为结果字符串分配内存,并将其初始化为输入字符串 s。同时处理字符串长度为1的特殊情况。

  1. 主循环
while (1) {
    for (int i = len - 1; i >= 0; i--) {
        if (result[i] < alphaBet[k - 1]) {
            result[i]++;
            for (int j = i + 1; j < len; j++) {
                result[j] = alphaBet[0];
            }
            if (isBeauty(result, len)) {
                return result;
            }
            break;
        } else {
            result[i] = alphaBet[0];
        }
    }

从字符串的末尾开始,逐个字符尝试将其增加,确保不包含回文子字符串。

  1. 检查所有字符是否达到最大值
    bool allMax = true;
    for (int i = 0; i < len; i++) {
        if (result[i] != alphaBet[k - 1]) {
            allMax = false;
            break;
        }
    }
    if (allMax) {
        break;
    }
}

free(result);
return strdup("");

检查是否所有字符都已经达到了最大值,如果是,则返回空字符串。

复杂度分析

  • 时间复杂度:O(n*k),因为每次字符的变化都需要检查整个字符串是否为美丽字符串。
  • 空间复杂度:O(n),因为需要额外的空间来存储结果字符串。

结果

在这里插入图片描述

官方题解

看不懂

char* generate(char* s, int idx, int offset) {
    char* res = (char*)malloc(sizeof(char) * (strlen(s) + 1));
    strcpy(res, s);
    res[idx] += offset;
    int len = strlen(s);
    for (int i = idx + 1; i < len; ++i) {
        char blockedCharacters[3] = {'\0'};
        for (int j = 1; j < 3; ++j) {
            if (i - j >= 0) {
                blockedCharacters[j - 1] = res[i - j];
            }
        }
        for (char c = 'a'; c <= 'c'; ++c) {
            int isBlocked = 0;
            for (int x = 0; x < 3; ++x) {
                if (blockedCharacters[x] == c) {
                    isBlocked = 1;
                    break;
                }
            }
            if (!isBlocked) {
                res[i] = c;
                break;
            }
        }
    }
    return res;
}

char * smallestBeautifulString(char * s, int k){
    int length = strlen(s);
    char* result = (char*)malloc(sizeof(char) * (length + 1));
    strcpy(result, "");
    for (int i = length - 1; i >= 0; --i) {
        char blockedCharacters[3] = {'\0'};
        for (int j = 1; j < 3; ++j) {
            if (i - j >= 0) {
                blockedCharacters[j - 1] = s[i - j];
            }
        }
        for (int j = 1; j < 4; ++j) {
            if (s[i] - 'a' + j + 1 <= k) {
                int isBlocked = 0;
                for (int x = 0; x < 3; ++x) {
                    if (blockedCharacters[x] == s[i] + j) {
                        isBlocked = 1;
                        break;
                    }
                }
                if (!isBlocked) {
                    sprintf(result, "%s", generate(s, i, j));
                    return result;
                }
            }
        }
    }
    return result;
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/lexicographically-smallest-beautiful-string/solutions/2814311/zi-dian-xu-zui-xiao-de-mei-li-zi-fu-chua-dr81/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:return,int,len,char,2663,字符串,字典,result
From: https://blog.csdn.net/qq_35085273/article/details/139889628

相关文章

  • 【广度优先搜索 深度优先搜索 图论】854. 相似度为 K 的字符串
    本文涉及知识点广度优先搜索深度优先搜索图论图论知识汇总深度优先搜索汇总C++BFS算法LeetCode854.相似度为K的字符串对于某些非负整数k,如果交换s1中两个字母的位置恰好k次,能够使结果字符串等于s2,则认为字符串s1和s2的相似度为k。给你两个字母......
  • [字符串专题] KMP、Hash、Trie
    KMP核心思想:在每次失配时,不是把p串往后移一位,而是把p串往后移动至下一次可以和前面部分匹配的位置,这样就可以跳过大多数的失配步骤。而每次p串移动的步数就是通过查找next数组确定的。KMP主要分两步:求next数组、匹配字符串,其难点在于如何求next数组for(inti=1,......
  • Hutool将Cron表达式转换为日期字符串
    在Java开发中,处理定时任务是常见的需求。Cron表达式是一种强大的工具,用于定义这些定时任务的执行时间。然而,有时我们需要将Cron表达式转换为具体的日期字符串,以便于展示或进一步处理。本文将介绍如何使用Hutool工具库来实现这一转换。准备工作在开始之前,确保你的项目中包含了......
  • 字符串---最常用的11个魔法
    join--连接符split--以字符分割strip--去除空格或者指定字符upper--全部字符大写lower--全部字符小写find--查找字符串中某个字符的索引值len()--计算字符长度range(0,100)--列出0,1,2,3...99的数字for循环--最常用的循环索引--比如test='......
  • 【C#】WPF 类库项目 无法创建 “资源字典” 文件
    解决办法打开项目工程文件(project.csproj)在标签添加下面红色的三句话<Deterministic>true</Deterministic><ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids><WarningLevel>......
  • c语言 字符串操作函数
    字符串操作函数1.strlen()函数strlen()函数用于计算字符串的长度,返回字符串的字符数。语法:size_tstrlen(constchar*str)参数:str–要计算长度的字符串。返回值:字符串的字符数。示例:#include<stdio.h>#include<string.h>intmain(){charstr[50]="......
  • day10 - 字符串
    目录1.API1.1API概述1.2如何使用API帮助文档2.String类2.1String类概述2.2String类的特点2.3String类的构造方法2.4创建字符串对象两种方式的区别2.5字符串的比较2.5.1==号的作用2.5.2equals方法的作用2.6用户登录案例2.6.1案例需求2.6.2代码实现2.7遍......
  • Java-英语字符串进行单词分割
    (摘自头歌)任务描述将一段英语字符串进行单词分割。相关知识需要掌握:如何将字符串进行分割。String.split()拆分字符串lang包String类的split()方法publicString[]split(Stringregex)publicString[]split(Stringregex,intlimit)//limit参数控制模式应用的次数,因......
  • sqlalchemy根据字典kv自定义表结构
    根据数据的内容自动创建数据库表结构fromsqlalchemyimportcreate_engine,Column,Integer,String,Float,Booleanfromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy.ormimportsessionmaker,Mapped,mapped_columnBase=declarative_base()......
  • Python优雅遍历字典删除元素的方法
    在Python中,直接遍历字典并在遍历过程中删除元素可能会导致运行时错误,因为字典在迭代时并不支持修改其大小。但是,我们可以通过一些方法间接地达到这个目的。1.方法一:字典推导式创建新字典(推荐)常见的方法是创建一个新的字典,其中不包含我们想要删除的元素。这可以通过字典推导式(dic......