ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[LeetCode] 1763. Longest Nice Substring

2022-02-01 02:31:44  阅读:175  来源: 互联网

标签:子串 substring int 字母 Substring 字符串 1763 nice Nice


A string s is nice if, for every letter of the alphabet that s contains, it appears both in uppercase and lowercase. For example, "abABB" is nice because 'A' and 'a' appear, and 'B' and 'b' appear. However, "abA" is not because 'b' appears, but 'B' does not.

Given a string s, return the longest substring of s that is nice. If there are multiple, return the substring of the earliest occurrence. If there are none, return an empty string.

Example 1:

Input: s = "YazaAay"
Output: "aAa"
Explanation: "aAa" is a nice string because 'A/a' is the only letter of the alphabet in s, and both 'A' and 'a' appear.
"aAa" is the longest nice substring.

Example 2:

Input: s = "Bb"
Output: "Bb"
Explanation: "Bb" is a nice string because both 'B' and 'b' appear. The whole string is a substring.

Example 3:

Input: s = "c"
Output: ""
Explanation: There are no nice substrings.

Constraints:

  • 1 <= s.length <= 100
  • s consists of uppercase and lowercase English letters.

最长的美好子字符串。

当一个字符串 s 包含的每一种字母的大写和小写形式 同时 出现在 s 中,就称这个字符串 s 是 美好 字符串。比方说,"abABB" 是美好字符串,因为 'A' 和 'a' 同时出现了,且 'B' 和 'b' 也同时出现了。然而,"abA" 不是美好字符串因为 'b' 出现了,而 'B' 没有出现。

给你一个字符串 s ,请你返回 s 最长的 美好子字符串 。如果有多个答案,请你返回 最早 出现的一个。如果不存在美好子字符串,请你返回一个空字符串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-nice-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这是一道官方定义的简单题,但是其实不是那么简单。

题意不难理解,乍一看像是滑动窗口可以解决的问题,但是仔细想想,滑动窗口左右指针移动的条件不好找。这里我提供一个分治的做法。首先我们遍历一遍 input 字符串,用 hashset 记录好每个字母出现的次数。我们再次扫描 input 字符串,此时对于我们遇到的每个字母,我们都用 hashset 判断一下这个字母是否大小写都存在,如果不满足这个条件,说明这个字母一定不在满足题意的子串内,换言之满足题意的子串一定在当前这个字母的左边或者右边。这就是分治的来源了。如果当前字母的大小写在 hashset 中都存在,则接着扫描,直到我们找到第一个有大小写缺失的字母,我们从这个字母开始做分治。这个做法时间复杂度最差是O(n^2),比如类似 "aaaaaaaaaa" 这种例子。

这里还有一个细节需要注意,我们需要返回的是最早出现的满足题意的子串,所以分治的时候尽量优先取靠左的子串。

时间O(n^2) - worst case

空间O(n) - hashset

Java实现

 1 class Solution {
 2     public String longestNiceSubstring(String s) {
 3         // corner case
 4         if (s.length() < 2) {
 5             return "";
 6         }
 7 
 8         // normal case
 9         char[] input = s.toCharArray();
10         HashSet<Character> set = new HashSet<>();
11         for (char c : input) {
12             set.add(c);
13         }
14 
15         for (int i = 0; i < input.length; i++) {
16             char c = input[i];
17             if (set.contains(Character.toUpperCase(c)) && set.contains(Character.toLowerCase(c))) {
18                 continue;
19             }
20             String sub1 = longestNiceSubstring(s.substring(0, i));
21             String sub2 = longestNiceSubstring(s.substring(i + 1));
22             return sub1.length() >= sub2.length() ? sub1 : sub2;
23         }
24         return s;
25     }
26 }

 

官方题解也提供了另外的做法,这里我再分享一个枚举的做法。这里我们需要用两个 for 循环去卡住子串。对于子串中的每个字母,我们都用位运算的办法去找这个字母对应的 ASCII 码与 A 或者 a 的差值,记为 lower 和 upper,取决于到底是大写字母还是小写字母。如果一个字母在子串中大写和小写都存在,那么这个字母的 lower 值和 upper 值应该是相同的。如果此时 for 循环的两个指针之间的距离即是符合题意的子串的长度。我们用这个办法去找到符合题意的最长的子串。注意这个做法中 j 指针是如何走的,跟一般两层的 for 循环有区别。

时间O(n^2)

空间O(1)

Java实现

 1 class Solution {
 2     public String longestNiceSubstring(String s) {
 3         int len = s.length();
 4         int maxPos = 0;
 5         int maxLen = 0;
 6         for (int i = 0; i < len; i++) {
 7             int lower = 0;
 8             int upper = 0;
 9             for (int j = i; j < len; j++) {
10                 if (Character.isLowerCase(s.charAt(j))) {
11                     lower |= 1 << (s.charAt(j) - 'a');
12                 } else {
13                     upper |= 1 << (s.charAt(j) - 'A');
14                 }
15                 if (lower == upper && j - i + 1 > maxLen) {
16                     maxPos = i;
17                     maxLen = j - i + 1;
18                 }
19             }
20         }
21         return s.substring(maxPos, maxPos + maxLen);
22     }
23 }

 

LeetCode 题目总结

标签:子串,substring,int,字母,Substring,字符串,1763,nice,Nice
来源: https://www.cnblogs.com/cnoodle/p/15858789.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有