java - 查找数组中是否存在多个非连续重复
问题描述
[c,a,a,b,b,d], [c,a,b,b,d,d,a] 或 [a,a,b,b,c,d,d] 应该返回 false 而 [ a,a,c,d,b,b] 或 [a,a,c,b,b,d] 应返回 true,因为重复项不连续。
public boolean findNSeqDup(String[] arr) {
if(arr.length < 4){
return false;
}
boolean isPrevDup = false;
String prevString = "";
for (int i = 0; i < arr.length; i++){
if(arr[i].equals(prevString) && isPrevDup==true){
System.out.println("true");
return true;
}
else if(arr[i].equals(prevString) && isPrevDup==false){
isPrevDup = true;
prevString = "";
}
else if(!prevString.equals("") && !arr[i].equals(prevString)){
prevString = "";
}
// for the first condition if the previous string is empty
else {
prevString = "";
}
prevString = arr[i];
}
System.out.println("false");
return false;
}
上面的代码对所有应该返回假的条件都返回真([c,a,a,b,b,d], [c,a,b,b,d,d,a] 或 [a,a,b ,b,c,d,d])。我究竟做错了什么?如果我使用堆栈或类似的数据结构,这会更容易吗?
解决方案
似乎使用堆栈/双端队列来收集连续重复和单打的计数可以帮助解决此任务:
public static boolean findNonConsDup(String ... arr) {
int n = arr.length;
if(n < 4) {
return false;
}
System.out.println(Arrays.toString(arr) + ": "); // debug print
Deque<Integer> freqs = new ArrayDeque<>();
String prev = arr[0];
int cnt = 1;
int prevFreq;
for (int i = 1; i < n; i++) {
if (!prev.equals(arr[i])) { // non-consecutive element found
if (freqs.isEmpty()) {
freqs.push(cnt);
}
else {
prevFreq = freqs.peek();
// store the count of elements only when a single changes the duplicate or vice versa
if (cnt == 1 && prevFreq > 1 || cnt > 1 && prevFreq == 1) {
freqs.push(cnt);
// early detection of non-consecutive duplicates
if (freqs.size() > 2) {
int p1 = freqs.pop();
int p2 = freqs.pop();
int p3 = freqs.pop();
// pattern found: at least 1 single separator between 2 duplicates
if (p1 > 1 && p2 == 1 && p3 > 1) {
return true;
} else { // restore queue
freqs.push(p3);
freqs.push(p2);
freqs.push(p1);
}
}
}
}
cnt = 1;
} else {
cnt++;
}
prev = arr[i];
}
prevFreq = freqs.peek();
if (cnt == 1 && prevFreq > 1 || cnt > 1 && prevFreq == 1) {
freqs.push(cnt);
}
System.out.print(freqs + " -> "); // debug print
return freqs.size() > 2 && freqs.pop() > 1 && freqs.pop() == 1 && freqs.pop() > 1;
}
测试:
public static void main(String args[]) {
System.out.println(findNonConsDup("c","a","b","d","a","d"));
System.out.println(findNonConsDup("c","a","b","b","a","d"));
System.out.println(findNonConsDup("c","a","b","b","b", "a","d", "d"));
System.out.println(findNonConsDup("c","a","a","b","b","d"));
System.out.println(findNonConsDup("c","a","b","b","d","d","a"));
System.out.println(findNonConsDup("a","a","b","b","c","d","d"));
System.out.println(findNonConsDup("c", "a","a","c","d","b","d","d"));
System.out.println(findNonConsDup("a","a","c","d","b","d","d"));
System.out.println(findNonConsDup("a","a","c","b","b","d","d"));
}
输出
[c, a, b, d, a, d]: [1] -> false
[c, a, b, b, a, d]: [1, 2, 1] -> false
[c, a, b, b, b, a, d, d]: [2, 1, 3, 1] -> true
[c, a, a, b, b, d]: [1, 2, 1] -> false
[c, a, b, b, d, d, a]: [1, 2, 1] -> false
[a, a, b, b, c, d, d]: [2, 1, 2] -> true
[c, a, a, c, d, b, d, d]: [2, 1, 2, 1] -> true
[a, a, c, d, b, d, d]: [2, 1, 2] -> true
[a, a, c, b, b, d, d]: true
推荐阅读
- vba - 过滤并循环遍历最小日期的记录列表
- remote-access - 使用远程桌面时未执行编码的 UI 测试脚本
- oracle - OBIEE 12c 管理工具 - 重复定义 - 元数据脚本执行错误
- javafx - 如何在 JavaFX 中创建一个只有原始外观关闭按钮的窗口?
- arrays - Swift 2 Object Mapper 类追加不起作用,结果为零
- r - 我可以拼凑一个我想要选择的列的名称吗?
- vba - 如果第一行为空,VBA If 语句跳过文件
- c# - GDI+ 保存时发生一般错误
- azure-devops - 发布带有工件的测试程序集,以便在 VSTS 的功能测试期间使用它们
- c# - 具有不同输入参数的类的工厂模式设计