gpt4 book ai didi

java - 字符串 1 中的最小窗口包含字符串 2 中的所有字符但不包含字符串 3 中的字符

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:21:22 25 4
gpt4 key购买 nike

好的,这是一道面试题。不,它不是 this question 的副本.

给定 3 个字符串 - str1str2str3:

str1 = "spqrstrupvqw"
str2 = "sprt"
str3 = "q"

我们必须在 str1 中找到最小窗口,其中包含所有来自 str2 的任意顺序的字符,但不包含来自 str3 的字符.在这种情况下,答案将是:"strup"

我想出了这段代码:

static String minimumWindow(String str1, String str2, String str3) {

class Window implements Comparable<Window> {
int start;
int end;

public Window(int start, int end) {
this.start = start;
this.end = end;
}

public int getEnd() {
return end;
}

public int getStart() {
return start;
}

public int compareTo(Window o) {
int thisDiff = end - start;
int thatDiff = o.end - o.start;

return Integer.compare(thisDiff, thatDiff);
}

@Override
public String toString() {
return "[" + start + " : " + end + "]";
}
}

// Create Sets of characters for "contains()" check

Set<Character> str2Chars = new HashSet<>();
for (char ch: str2.toCharArray()) {
str2Chars.add(ch);
}

Set<Character> str3Chars = new HashSet<>();
for (char ch: str3.toCharArray()) {
str3Chars.add(ch);
}

// This will store all valid window which doesn't contain characters
// from str3.
Set<Window> set = new TreeSet<>();

int begin = -1;

// This loops gets each pair of index, such that substring from
// [start, end) in each window doesn't contain any characters from str3
for (int i = 0; i < str1.length(); i++) {
if (str3Chars.contains(str1.charAt(i))) {
set.add(new Window(begin, i));
begin = i + 1;
}
}

int minLength = Integer.MAX_VALUE;
String minString = "";

// Iterate over the windows to find minimum length string containing all
// characters from str2
for (Window window: set) {
if ((window.getEnd() - 1 - window.getStart()) < str2.length()) {
continue;
}

for (int i = window.getStart(); i < window.getEnd(); i++) {
if (str2Chars.contains(str1.charAt(i))) {
// Got first character in this window that is in str2
// Start iterating from end to get last character
// [start, end) substring will be the minimum length
// string in this window
for (int j = window.getEnd() - 1; j > i; j--) {
if (str2Chars.contains(str1.charAt(j))) {
String s = str1.substring(i, j + 1);

Set<Character> sChars = new HashSet<>();
for (char ch: s.toCharArray()) {
sChars.add(ch);
}

// If this substring contains all characters from str2,
// then only it is valid window.
if (sChars.containsAll(str2Chars)) {
int len = sChars.size();
if (len < minLength) {
minLength = len;
minString = s;
}
}
}
}
}
}
}

// There are cases when some trailing and leading characters are
// repeated somewhere in the middle. We don't need to include them in the
// minLength.
// In the given example, the actual string would come as - "rstrup", but we
// remove the first "r" safely.
StringBuilder strBuilder = new StringBuilder(minString);

while (strBuilder.length() > 1 && strBuilder.substring(1).contains("" + strBuilder.charAt(0))) {
strBuilder.deleteCharAt(0);
}

while (strBuilder.length() > 1 && strBuilder.substring(0, strBuilder.length() - 1).contains("" + strBuilder.charAt(strBuilder.length() - 1))) {
strBuilder.deleteCharAt(strBuilder.length() - 1);
}

return strBuilder.toString();
}

但它并不适用于所有测试用例。它确实适用于此问题中给出的示例。但是当我提交代码时,有 2 个测试用例失败了。不,我不知道它失败的测试用例。

即使在尝试了各种示例输入之后,我也找不到失败的测试用例。有人可以看看代码有什么问题吗?如果有人能提供更好的算法(只是伪代码),我将不胜感激。我知道这确实不是优化的解决方案。

最佳答案

str1 = "spqrstrupvqw"
str2 = "sprt"
str3 = "q"

我们正在寻找 str1 中的最小子串包含所有 str2字符(假定已排序) 并且没有来自str3 的字符..

i = 1 .. str1.length
cursor = 1 .. str2.length

解决方案必须在表格上:

str2.first X X .. X X str2.last

因此,为了检查该子字符串,我们在 str2 上使用光标, 但我们也有避免 str3 的约束字符,所以我们有:

if str3.contain(str1[i])
cursor = 1
else
if str1[i] == str2[cursor]
cursor++

目标检查是:

if cursor > str2.length
return solution
else
if i >= str1.length
return not-found

为了优化,您可以跳到下一个预测:

look-ahead = { str2[cursor] or { X | X in str3 }}

万一str2 未排序:

i = 1 .. str1.length
lookup = { X | X in str2 }

解决方案必须在表格上:

str2[x] X X .. X X str2[x]

因此,为了检查该子字符串,我们使用检查列表 str2 , 但我们也有避免 str3 的约束字符,所以我们有:

if str3.contain(str1[i])
lookup = { X | X in str2 }
else
if lookup.contain(str1[i])
lookup.remove(str1[i])

目标检查是:

if lookup is empty
return solution
else
if i >= str1.length
return not-found

为了优化,您可以跳到下一个预测:

look-ahead = {{ X | X in lookup } or { X | X in str3 }}

代码

class Solution
{
private static ArrayList<Character> getCharList (String str)
{
return Arrays.asList(str.getCharArray());
}

private static void findFirst (String a, String b, String c)
{
int cursor = 0;
int start = -1;
int end = -1;

ArrayList<Character> stream = getCharList(a);
ArrayList<Character> lookup = getCharList(b);
ArrayList<Character> avoid = getCharList(c);

for(Character ch : stream)
{
if (avoid.contains(ch))
{
lookup = getCharList(b);
start = -1;
end = -1;
}
else
{
if (lookup.contains(ch))
{
lookup.remove(ch)

if (start == -1) start = cursor;

end = cursor;
}
}

if (lookup.isEmpty())
break;

cursor++;
}

if (lookup.isEmpty())
{
System.out.println(" found at ("+start+":"+end+") ");
}
else
{
System.out.println(" not found ");
}
}
}

关于java - 字符串 1 中的最小窗口包含字符串 2 中的所有字符但不包含字符串 3 中的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23228960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com