首页 > 试题广场 >

小红的双生串

[编程题]小红的双生串
  • 热度指数:3995 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}小红定义一个字符串是双生串,当且仅当其前半部分所有字符相同,后半部分所有字符相同。
\hspace{15pt}现在,小红拿到了一个字符串 s ,她每次操作可以修改一个字符。小红希望你求出将其修改为双生串的最小修改次数。

输入描述:
\hspace{15pt}在一行上输入一个长度为 1 \leqq {\rm len}(s) \leqq 2 \times 10^5 且为偶数,仅由小写字母构成的字符串 s,代表待修改的字符串。


输出描述:
\hspace{15pt}输出一个整数,表示将 s 修改为双生串的最小修改次数。
示例1

输入

popipa

输出

3

说明

\hspace{15pt}在这个样例中,将 s 修改为 \texttt{ 是其中一个最优解。
示例2

输入

aaaa

输出

0

说明

\hspace{15pt}在这个样例中,给定的字符串已经是双生串,不需要修改。
import java.util.*;

public class Main {
    
    // 本质上就是用前半段/后半段的总长度减去出现次数最多的字符的数量
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String input = in.nextLine();
        String first = input.substring(0, input.length() / 2);
        String last = input.substring(input.length() / 2);
        Map<Character, Integer> firstMap = getMap(first);
        Map<Character, Integer> lastMap = getMap(last);
        int times = getCount(firstMap) + getCount(lastMap);
        System.out.print(times);
    }

    private static Map<Character, Integer> getMap(String str) {
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            map.put(ch, map.getOrDefault(ch, 0) + 1);
        }
        return map;
    }

    private static int getCount(Map<Character, Integer> map) {
        if (map.size() == 1) { // 代表只有一种字母,不需要修改
            return 0;
        }
        int maxValue = 0; // 获取到出现次数最多的字符串
        int length = 0;
        for (char key : map.keySet()) {
            int value = map.get(key);
            length += value;
            if (value > maxValue) {
                maxValue = value;
            }
        }
        // 用总长度减去最多的字符串数量
        return length - maxValue;
    }
}

发表于 2025-12-09 14:42:20 回复(0)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String str = scan.nextLine();
        if(str.length() % 2 != 0){
            return;
        }
        String sub = str.substring(0, str.length() / 2);
        String sub1 = str.substring(str.length() / 2);
        Map<Character, Integer> frontMap = new HashMap<>();
        Map<Character, Integer> endMap = new HashMap<>();
        for (int i = 0; i < sub.length(); i++) {
            frontMap.put(sub.charAt(i), frontMap.getOrDefault(sub.charAt(i), 0) + 1);
            endMap.put(sub1.charAt(i), endMap.getOrDefault(sub1.charAt(i), 0) + 1);
        }
        int max1 = 0;
        for (int i = 0; i < sub.length(); i++) {
            max1 = Math.max(max1, frontMap.get(sub.charAt(i)));
        }
        int max2 = 0;
        for (int i = 0; i < sub1.length(); i++) {
            max2 = Math.max(max2, endMap.get(sub1.charAt(i)));
        }
        System.out.println(str.length() - max1 - max2);
    }
}
发表于 2025-11-30 13:59:17 回复(0)
java实现,注意题目描述是前半部分都一样,后半部分都一样,左右两部分长度必须相等!用left和right数组分别统计左半部分的各元素出现次数和右半部分各元素出现次数,为了让左半部分都是一个字母,需要修改次数为左半部分的长度 - 左半部分统计的最大次数。同理,右半部分也是一样,最后把两者相加即可得到结果7.19
import java.util.Scanner;
import java.util.Arrays;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String s = in.nextLine();
            int mid = s.length() / 2 - 1;
            int[] left = new int[26];
            int[] right = new int[26];
            for (int i = 0; i <= mid; i++){
                left[s.charAt(i) - 'a']++;
                right[s.charAt(i + mid + 1) - 'a']++;
            }
            Arrays.sort(left);
            Arrays.sort(right);
            System.out.println((mid + 1 - left[25]) + (mid + 1 - right[25]));
        }
    }
}

发表于 2025-07-19 14:23:38 回复(0)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String str = in.nextLine();
            String s1 = str.substring(0, str.length() / 2);
            String s2 = str.substring(str.length() / 2);
            int result = dealStr(s1) + dealStr(s2);
            System.out.println(result);
        }
    }

    private static int dealStr(String str) {
        Map<Character, Integer> map = new HashMap<Character, Integer>();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
        List<Integer> list = new ArrayList<>();
        map.forEach((kay, value)-> {
            list.add(value);
        });
        Collections.sort(list);
        int max = list.get(list.size() - 1);
        return str.length() - max;
    }
}
发表于 2025-04-01 17:16:46 回复(0)