zoukankan      html  css  js  c++  java
  • 移除字符串中重复的字符

    原文:

    Design an algorithm and write code to remove the duplicate characters in a string without using any additional buffer. NOTE: One or two additional variables are fine. An extra copy of the array is not.

    译文:

    设计算法并写出代码移除字符串中重复的字符,不能使用额外的缓存空间。注意: 可以使用额外的一个或两个变量,但不允许额外再开一个数组拷贝。

    解答:

    这道题目其实是要你就地将字符串中重复字符移除。但需要确定一点, 不能使用额外的一份数组拷贝是指根本就不允许开一个数组,还是说可以开一个固定大小, 与问题规模(即字符串长度)无关的数组。

    1. 若是根本就不允许开一个数组,那没办法了,遍历数组,每访问一个字符,然后将其后的重复字符删除,时间复杂度为O(n^2)。
        public String removeRepeatChar1(String s){
            
            if(s == null || "".equals(s)){
                return s;
            }
            
            StringBuffer Str = new StringBuffer(s);
            
            for(int i = 0; i < Str.length(); i++){
                char temp = Str.charAt(i);
                //从后往前删,不会出现数组越界问题
                for(int j = Str.length()-1; j > i ; j--){
                    if(temp == Str.charAt(j)){
                        Str.deleteCharAt(j);
                    }
                }
            }
            return Str.toString();
        }

      2.如果可以开一个固定大小,与问题规模(即字符串长度)无关的数组,那么可以用一个数组来 表征每个字符的出现(假设是ASCII字符,则数组大小为256),这样的话只需要遍历一遍字符 串即可,时间复杂度O(n)。下面的方法使用位向量存储字符是否重复,也可以申请一个boolean数组,长度为256(针对ASCII)

        public String removeRepeatChar2(String s){
            
            //若该字符串是ASCII编码,用位向量存储
            if(s == null || "".equals(s)){
                return s;
            }
            final int CONSTANT = 32;
            //数组皆为0
            int[] ints = new int[8];
            
            StringBuffer str = new StringBuffer(s);
            str = str.reverse();
            //删除是从后往前删
            for(int i = str.length()-1;i>=0;i--){
                //商,判断在哪个数组
                int ids = str.charAt(i) / CONSTANT;
                //余数,判断在数组的第几位
                int shift = str.charAt(i) % CONSTANT;
                /**
                 * 当前位是1,则返回true,说明前面该字符出现过
                 * 当前位是0,则置为1。
                 */
                if((ints[ids] & 1<< shift) > 0)
                    str.deleteCharAt(i);
                else
                    ints[ids] =  ints[ids] | 1<< shift;
            }
            str = str.reverse();
            return str.toString();
        }
    身体是革命的本钱,爱跑步,爱生活!
  • 相关阅读:
    51NOD 1069 Nim游戏
    51NOD 1066 Bash游戏
    51NOD 1058 N的阶乘的长度
    51NOD 1057 N的阶乘
    51NOD 1027 大数乘法
    RMQ 区间最大值 最小值查询
    Codeforces Round #426 (Div. 2) C. The Meaningless Game
    51NOD 1046 A^B Mod C
    OJ上 编译器 G++和C++的区别
    二分暑假专题 训练记录 2017-7-29
  • 原文地址:https://www.cnblogs.com/caozx/p/9188143.html
Copyright © 2011-2022 走看看