递归去除字符串重复字符(保留首次出现)的代码问题求助
递归去除字符串重复字符(保留首次出现,不使用集合)
需求:递归去除字符串中重复出现的字符,仅保留每个字符的首次出现(重复可连续或非连续),且不使用任何集合类。例如输入RAMAAM,期望输出RAM,但现有代码调用remove时始终传入相同值'A',逻辑陷入混乱。
原代码问题分析
- 滥用类成员变量:
i、j、newStr、count等全局变量会被所有递归调用共享,导致循环索引无法正确重置,字符统计逻辑混乱。比如j在remove方法的while循环后不会重置,下次调用时直接从上次位置继续遍历;i作为全局变量,递归时无法回溯到上一层状态。 - 递归逻辑错误:
removeDuplicates每次递归都传入原始字符串,未将问题拆解为更小的子问题(如处理剩余子串),递归调用后直接返回newStr,未正确组合递归结果。 - 非递归的辅助方法:
remove用while循环遍历字符串,仅统计单个字符的出现次数,未与递归流程结合,无法实现整体去重。
正确递归实现
核心思路:将问题拆解为子问题——处理当前字符串的第一个字符,递归处理剩余子串时先移除所有与第一个字符相同的字符,再将第一个字符与处理后的子串拼接。全程无全局变量,每个递归调用状态独立。
class RecursionRemoveDuplicatesFromString { String removeDuplicates(String s) { // 基准情况:空字符串或单个字符直接返回 if (s == null || s.length() <= 1) { return s; } // 取第一个字符 char firstChar = s.charAt(0); // 递归处理剩余子串,同时移除所有和firstChar相同的字符 String processedRest = removeDuplicates(removeAllOccurrences(s.substring(1), firstChar)); // 拼接第一个字符和处理后的子串 return firstChar + processedRest; } // 辅助递归方法:移除字符串中所有指定字符 String removeAllOccurrences(String s, char target) { if (s.length() == 0) { return ""; } // 当前字符等于目标字符则跳过,递归处理剩余部分 if (s.charAt(0) == target) { return removeAllOccurrences(s.substring(1), target); } else { // 保留当前字符,拼接递归处理后的剩余部分 return s.charAt(0) + removeAllOccurrences(s.substring(1), target); } } public static void main(String[] args) { String s = "RAMAAM"; RecursionRemoveDuplicatesFromString remover = new RecursionRemoveDuplicatesFromString(); System.out.println(remover.removeDuplicates(s)); // 输出RAM } }
逻辑说明
removeDuplicates主方法:- 基准判断:空字符串或单个字符直接返回,无需去重。
- 提取首字符后,递归处理剩余子串——先通过
removeAllOccurrences移除剩余子串中所有与首字符相同的内容,确保子串不再包含当前首字符。 - 拼接首字符与处理后的子串,得到最终去重结果。
removeAllOccurrences辅助方法:纯递归实现字符移除,每次判断首字符是否为目标字符,是则跳过,否则保留并递归处理剩余部分。
内容的提问来源于stack exchange,提问作者nik
相关产品推荐
相关产品推荐

