字符消消乐,消除相邻重复字符

前几天遇到一个算法题,跟大家分享一下,没有用框架(主要是当时听了这个题目有点懵逼,想不起来用啥框架了,所以用了最基础的Java知识来完成的,分享给大家,欢迎各位高手提供更优秀的方法,一起学习一起进步)

题目要求:

给定一个字符串,里面可能存在重复字符,请消除相邻的重复字符,类似于水果消消乐,只不过水果消消乐是消除三个同样形状,相同颜色的,他要求只要重复就消除;给出字符串如下:

abbbaadeffc  ---->dec

第一次bbb靠在一起被消除了,然后aaa在一起了又被消除了,接下来ff在一起也被消除了,那么就只有def不重复所以输出。这个呢是要求消除相邻重复则,下面这种应该是要保留的:

abbbcdeffc---->acdec  c虽说出现了2次,但是不是相邻的,所以要保留。

上实现代码如下,欢迎各位大佬指点,在此谢过:

import java.util.ArrayList;
import java.util.List;

public class StringDelete {

    public static void main(String[] args) {

        // String originalStr = "abbbaadeffc";
        String originalStr="abbbcdeffc";
        List<String> originalCharsList = new ArrayList<>();
        // 只是为了把字符串转换为数组
        for (int k = 0; k < originalStr.length(); k++) {
            originalCharsList.add(String.valueOf(originalStr.charAt(k)));
        }

        RemoveDuplicateChars(originalCharsList);
    }


    /**
     * 消除重复字符的主方法
     * @param input 输入的字符数组
     */
    public static void RemoveDuplicateChars(List<String> input) {

        // 用来记录字符所在的索引位置,也是消除重复字符的起始位置
        Integer startIndex = 0;
        // 重复字符出现的次数
        Integer repeatTimes = 0;
        // 标记一下当前获取到的字符  用来跟后面的字符比较,判断是否重复出现
        String currentChar = "";
        // 如果输入为空那就不用干活了,收拾东西下班回家
        if (input == null || input.isEmpty()) {
            return;
        }
        // 循环输入字符数组
        for (int i = 0; i < input.size(); i++) {
            // 如果第一次的话就先做个赋值操作,这个感觉跟下面else反过来效率更好一些
            if (currentChar == "") {
                // 获取当前循环的字符
                currentChar = input.get(i);
                // 记录字符所在的位置(索引)
                startIndex = i;
                // 字符出现了一次
                repeatTimes++;
                continue;

            } else {
                // 如果上一个字符和当前字符相同,重复次数加一
                if (currentChar.equals(input.get(i))) {
                    repeatTimes++;
                } else { //如果当前字符跟上一个记录的字符不相同的话走else分支
                    if (repeatTimes > 1) {  // 如果重复次数大于一,说明至少出现2次,可以消除
                        // 消除重复字符,跳出当前循环(为啥不继续循环?)
                        input = removeDumpChars(input, startIndex, repeatTimes);
                        break;
                    }
                    // 如果只出现了一次,则执行跟第一次获取字符一样的操作,
                    currentChar = input.get(i);
                    startIndex = i;
                    repeatTimes = 1;// 重复次数要重置为1
                }
            }

        }
        // 这里判断入股哦重复次数大于1  那么有可能还有重复字符,继续调用自己执行消除重复字符的方法
        if (repeatTimes > 1) {
            RemoveDuplicateChars(input);
        } else {
            // 说明没有重复字符了,那么输出最终结果即可
            for (String item : input) {
                System.out.println(item);
            }
        }
    }

    /**
     * 具体用来消除重复字符的方法(这个做法多种多样,用最原始的一种)
     * @param input
     * @param startIndex
     * @param repeatTimes
     * @return
     */
    static List<String> removeDumpChars(List<String> input, Integer startIndex, Integer repeatTimes) {

        List<String> resultList = new ArrayList<>();

        // 循环数组,把不在消除范围内的字符放到新数组中返回
        for (int i = 0; i < input.size(); i++) {
            if (i < startIndex || i >= startIndex + repeatTimes) {
                resultList.add(input.get(i));
            }
        }

        return resultList;
    }


}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值