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;
	}

在这里插入图片描述

posted @ 2023-02-15 16:39  兑生  阅读(16)  评论(0)    收藏  举报  来源
Live2D