AcWing 1460. 我在哪?(二分) java

👵 参考
👵 暴力破解 O(n^2)
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String s = sc.next();
for (int i = 1; i <= n; i++)// 枚举答案 K 的所有可能
{
Set<String> set = new HashSet<>();
boolean flag = true;// 记录字符串是否重复
for (int j = 0; j <= n - i; j++)
{
// String.substring(开始下标(包含),结束下标(不包含))
String t = s.substring(j, i+j);// 枚举 长度为K的所有子串
if (set.contains(t))
{
flag = false;// 重复
break;
}
set.add(t);// 借助哈希表去重
}
// 所有 k 长度的子串都无重复,又因长度 k 是从小到大枚举的,所以这就是最小的长度
if (flag == true)
{
System.out.println(i);
break;
}
}
}
👵 二分优化版 O(n logn)
static int n;
static String s;
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
s = sc.next();
// 二分 来求最小不重复子串
int l = 1;
int r = n;
while (l < r)
{
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
System.out.println(l);
}
/**
* @param mid 中点数
* @return true:答案比中点小 false:答案比中点大
*/
static boolean check(int mid)
{
HashSet<String> hashSet = new HashSet<>();
for (int i = 0; i + mid <= s.length(); i++)
{
String ss = s.substring(i, i + mid);
if (hashSet.contains(ss))
{
return false;
}
hashSet.add(ss);
}
return true;
}


浙公网安备 33010602011771号