题目描述
给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度,字符串本身是其最长的子串,子串要求:
1、 只包含1个字母(a~z, A~Z),其余必须是数字;
2、 字母可以在子串中的任意位置;
如果找不到满足要求的子串,如全是字母或全是数字,则返回-1。
输入描述
字符串(只包含字母和数字)
输出描述
子串的长度
用例
输入 | abC124ACb |
输出 | 4 |
说明 | 满足条件的最长子串是C124或者124A,长度都是4 |
输入 | a5 |
输出 | 2 |
说明 | 字符串自身就是满足条件的子串,长度为2 |
输入 | aBB9 |
输出 | 2 |
说明 | 满足条件的子串为B9,长度为2 |
输入 | abcdef |
输出 | -1 |
说明 | 没有满足要求的子串,返回-1 |
题目解析
此题可以用滑动窗口求解。
滑动窗口的左指针开始指向索引0,右指针也是从索引0开始不断向右移动,当右指针遇到字母时,则滑动窗口内部含字母量+1。
当滑动窗口内部含有两个字母时,存在如下情况:
此时,我们需要移动left指针来达到减少一个字母的目的,但是单纯的left++就能减少一个字母吗?
我们可以看看上面第三个圈的情况,当left指针指向的是数字,如果left++,则滑动窗口内的字母并不会减少。
因此,我们需要判断left指针当前指向的元素是否为字母,如果为字母,则left++才能起到减少一个字母的作用,否则不能。
那么当left指针当前指向的是数字,则left指针应该如何跳转呢?
如上面第三个圈内所示,貌似是直接 left = right,但是真是这样吗?请看下面例子
从上面例子可以看出,当left指针指向数字,但是滑动窗口内已经有两个字母时,left应该移动到第一个字母的后面一个位置target。target位置只有两种数据:字母或数字,如果是字母则target位置就是滑动窗口内第二字母的位置,如果是数字,则避免了长度损失。
而为了能够准确跳转到滑动窗口内第一个字母后面一个位置,我们在right指针扫描过程中,就需要记录字母所在的索引。
JS算法源码
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.on("line", (line) => {
console.log(getResult(line));
});
/* 滑动窗口 */
function getResult(s) {
let maxLen = -1;
let l = 0,
r = 0;
let hasLetter = false;
const letterIdx = [];
while (r < s.length) {
if (isLetter(s[r])) {
hasLetter = true;
letterIdx.push(r);
if (letterIdx.length > 1) {
l = letterIdx.shift() + 1;
}
if (r == l) {
r++;
continue;
}
}
maxLen = Math.max(maxLen, r - l + 1);
r++;
}
if (!hasLetter) return -1;
return maxLen;
}
function isLetter(c) {
return (c >= "a" && c <= "z") || (c >= "A" && c <= "Z");
}
Java算法源码
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(getResult(sc.next()));
}
private static int getResult(String str) {
int maxLen = -1;
boolean hasLetter = false;
int l = 0, r = 0;
LinkedList<Integer> letterIdx = new LinkedList<>();
while (r < str.length()) {
char c = str.charAt(r);
if (isLetter(c)) {
hasLetter = true;
letterIdx.add(r);
if (letterIdx.size() > 1) {
l = letterIdx.removeFirst() + 1;
}
if (r == l) {
r++;
continue;
}
}
maxLen = Math.max(maxLen, r - l + 1);
r++;
}
if (!hasLetter) return -1;
return maxLen;
}
public static boolean isLetter(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
}
Python算法源码
# 输入获取
s = input()
# 算法入口
def getResult():
maxLen = -1
l = 0
r = 0
letterIdx = []
hasLetter = False
while r < len(s):
if s[r].isalpha():
hasLetter = True
letterIdx.append(r)
if len(letterIdx) > 1:
l = letterIdx.pop(0) + 1
if r == l:
r += 1
continue
maxLen = max(maxLen, r - l + 1)
r += 1
if not hasLetter:
return -1
return maxLen
# 算法调用
print(getResult())
C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX(a,b) ((a) > (b) ? (a) : (b))
typedef struct ListNode{
int ele;
struct ListNode* next;
} ListNode;
typedef struct {
int size;
ListNode* head;
ListNode* tail;
} LinkedList;
LinkedList* new_LinkedList();
void addLast_LinkedList(LinkedList* link, int ele);
int removeFirst_LinkedList(LinkedList* link);
int main() {
char s[100000];
gets(s);
int maxLen = -1;
int hasLetter = 0;
int l = 0;
int r = 0;
LinkedList* letterIdx = new_LinkedList();
int len = strlen(s);
while(r < len) {
char c = s[r];
if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
hasLetter = 1;
addLast_LinkedList(letterIdx, r);
if(letterIdx->size > 1) {
l = removeFirst_LinkedList(letterIdx) + 1;
}
if(r == l) {
r++;
continue;
}
}
maxLen = MAX(maxLen, r - l + 1);
r++;
}
if(!hasLetter) {
puts("-1");
} else {
printf("%dn", maxLen);
}
return 0;
}
LinkedList* new_LinkedList() {
LinkedList* link = (LinkedList*) malloc(sizeof(LinkedList));
link->size = 0;
link->head = NULL;
link->tail = NULL;
return link;
}
void addLast_LinkedList(LinkedList* link, int ele) {
ListNode* node = (ListNode*) malloc(sizeof(ListNode));
node->ele = ele;
node->next = NULL;
if(link->size == 0) {
link->head = node;
link->tail = node;
} else {
link->tail->next = node;
link->tail = node;
}
link->size++;
}
int removeFirst_LinkedList(LinkedList* link) {
if(link->size == 0) exit(-1);
ListNode* removed = link->head;
if(link->size == 1) {
link->head = NULL;
link->tail = NULL;
} else {
link->head = link->head->next;
}
link->size--;
int res = removed->ele;
free(removed);
return res;
}
免责声明:
1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文
评论0