【编码题】字符串S由小写字母构成,长度为n。定义一种操作,每次都可以挑选字符串中任意的两个相邻字母进行交换。询问在至多交换m次之后,字符串中最多有多少个连续的位置上的字母相同?
【编码题】字符串S由小写字母构成,长度为n。定义一种操作,每次都可以挑选字符串中任意的两个相邻字母进行交换。询问在至多交换m次之后,字符串中最多有多少个连续的位置上的字母相同?
第一行为一个字符串S与一个非负整数m。(1 <= |S| <= 1000, 1 <= m <= 1000000)
一个非负整数,表示操作之后,连续最长的相同字母数量。
abcbaa 2
2
使2个字母a连续出现,至少需要3次操作。即把第1个位置上的a移动到第4个位置。 所以在至多操作2次的情况下,最多只能使2个b或2个a连续出现。
import java.util.*; public class Main{ static int res = 1; public static void main(String[] args){ Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); String str = input.split(" ")[0]; int m = Integer.parseInt(input.split(" ")[1]); HashMap<Character, List<Integer>> map = new HashMap<>(); char[] chars = str.toCharArray(); int len = chars.length; for(int i = 0; i < len; i++){ List<Integer> list = map.getOrDefault(chars[i], new ArrayList<>()); list.add(i); map.put(chars[i], list); } for(int i = 0; i < len; i++){ char c = chars[i]; List<Integer> list = map.get(c); moveTogether(list, i, m); /* int lessCount = 0; for(int num : list){ if(num < i){ lessCount++; } else{ break; } } int greatCount = list.size()-1-lessCount; for(int j = 0; j < lessCount; i++){ int cur = list.get(j); // 现在这个节点的位置在cur,要移动到 (0 1 j 3 4 ... lessCount-1)i // lesscount-2的时候对应i-2 // lesscount-1的时候对应i-1 int target = i + j - lessCount; int times = } } */ } System.out.println(res); } // 在times步内,尽可能把list里面的数字移动到mid周围 public static void moveTogether(List<Integer> list, int mid, int times){ int len = list.size(); int mid_index = 0; for(int i = 0; i < len; i++){ if(list.get(i) == mid){ mid_index = i; break; } } int left_index = mid_index-1; int right_index = mid_index+1; int count = 1; // mid为中心的左右边界 int left_mid = mid-1; int right_mid = mid+1; while(times > 0){ if(left_index < 0 && right_index >= len){ break; } // 看一下左边和右边哪个更近一点 int left_dist; if(left_index < 0) left_dist = Integer.MAX_VALUE / 2; else left_dist = left_mid - list.get(left_index); int right_dist; if(right_index >= len) { right_dist = Integer.MAX_VALUE / 2; } else { right_dist = list.get(right_index) - right_mid; } if(left_dist > right_dist){ // 右边靠更加近一点 if(times < right_dist) break; times -= right_dist; right_mid++; count++; right_index++; } else{ if(times < left_dist) break; times -= left_dist; left_mid--; left_index--; count++; } } res = Math.max(count, res); } }