Java 如何递归删除所有相邻的重复项

Java 如何递归删除所有相邻的重复项,java,algorithm,Java,Algorithm,我无法找到一个最佳解决方案(O(n)时间)来递归地从字符串中删除相邻的重复项。我的尝试: public static String removeDuplicate(String s) { if ( s == null ) return null; if ( s.length() <= 1 ) return s; if( s.substring(1,2).equals(s.substring(0,1))) return removeDuplicate(s.su

我无法找到一个最佳解决方案(O(n)时间)来递归地从字符串中删除相邻的重复项。我的尝试:

public static String removeDuplicate(String s) {
   if ( s == null ) return null;
   if ( s.length() <= 1 ) return s;
   if( s.substring(1,2).equals(s.substring(0,1))) 
      return removeDuplicate(s.substring(1));
   else return s.substring(0,1) + removeDuplicate(s.substring(1));
}
public静态字符串removedupplicate(字符串s){
如果(s==null)返回null;
如果(s.长度()“ay”
在上述情况下,这些是字符串转换:

阿兹克西 阿兹 嗯

输入输出示例:

输入:azxxzy输出:ay

输入:caaabbaacdddd输出:空字符串

输入:ACAABBBACDDD输出:acac

更新


我已经在下面发布了答案的一个版本。

正如你问题的评论中提到的,
String
操作已经是O(n)由于
字符串
是不可变的。这可以通过使用
字符
s数组来解决。由于您也在删除内容,因此还应该在该数组中使用
null
s,以防止每次删除字符时都必须移动内容。最后,您需要对数组t进行额外的传递o将其转换为字符串

你要问的真正问题更简单。从像
azxxzy
这样的字符串中删除
xx
将使
xx
前后的字符彼此相邻,它们可能是相同的。因此只需再次检查:将光标放在前面一点。继续使用字符串
zzy
,而不是使用
zy

复杂性将保持为O(n),因为每个字符最多检查两次,最多可以删除一次


由于您特别要求递归答案,我将假定这是一个家庭作业练习,并将实现留给您(使用
字符
数组,并将起始位置的索引作为额外参数添加到方法中)。非递归算法将更高效,也更易于实现!

正如您问题的评论中提到的,
字符串操作已经是O(n)由于
字符串
是不可变的。这可以通过使用
字符
s数组来解决。由于您也在删除内容,因此还应该在该数组中使用
null
s,以防止每次删除字符时都必须移动内容。最后,您需要对数组t进行额外的传递o将其转换为字符串

你要问的真正问题更简单。从像
azxxzy
这样的字符串中删除
xx
将使
xx
前后的字符彼此相邻,它们可能是相同的。因此只需再次检查:将光标放在前面一点。继续使用字符串
zzy
,而不是使用
zy

复杂性将保持为O(n),因为每个字符最多检查两次,最多可以删除一次


由于您特别要求递归答案,我将假定这是一个家庭作业练习,并将实现留给您(使用
字符
数组,并将起始位置的索引作为额外参数添加到方法中)。一个非递归算法将更有效,也更容易实现!

我将其转换为字符数组。此外,我不确定这在中完成的速度有多快,但您的问题似乎没有强调O时间,您只需要一个有效的算法(如果我正确阅读您的问题的话)

转换为字符数组意味着您不必使用字符串,因为字符串是不可变的(因此每次进行更改时都必须重新构建它们)


我把它转换成了一个字符数组。我也不确定这在中完成的速度有多快,但你的问题似乎并没有强调O时间,你只是想要一个有效的(如果我没有看错你的问题的话)

转换为字符数组意味着您不必使用字符串,因为字符串是不可变的(因此每次进行更改时都必须重新构建它们)


我提出了这个丑陋的解决方案,JasonC的想法(实际上是我没有追求的第一个想法)是在输出中添加字符,以防从输出中删除相邻的重复字符

public static String removeDuplicate(String s) {
 StringBuilder builder = new StringBuilder();
 char lastchar = '\0';
 for (int i = 0; i < s.length(); i++) {
   String str = builder.toString();
   if (!str.equals("")
       && (str.charAt(str.length() - 1) == s.charAt(i))) {
     builder.deleteCharAt(str.length() - 1);
   } else if (s.charAt(i) != lastchar)
     builder.append(s.charAt(i));
   lastchar = s.charAt(i);
 }
return builder.toString();
}
public静态字符串removedupplicate(字符串s){
StringBuilder=新的StringBuilder();
char lastchar='\0';
对于(int i=0;i
更新 但最好的解决办法是:在

publicstaticstringremoveduplicates(strings){
如果(s.isEmpty()){
返回s;
}
char[]buf=s.toCharArray();
char lastchar=buf[0];
//i:输入字符的索引
//o:输出字符的索引
INTO=1;
对于(int i=1;i0&&buf[i]==buf[o-1]){
lastchar=buf[o-1];
而(o>0&&buf[o-1]==lastchar){
o--;
}
}else if(buf[i]==lastchar){
//不要复制到输出
}否则{
buf[o++]=buf[i];
}
}
返回新字符串(buf,0,o);
}

我想出了这个丑陋的解决方案,JasonC的想法(实际上是我没有追求的第一个想法)是将字符附加到输出中,以防从输出中删除相邻的重复字符

public static String removeDuplicate(String s) {
 StringBuilder builder = new StringBuilder();
 char lastchar = '\0';
 for (int i = 0; i < s.length(); i++) {
   String str = builder.toString();
   if (!str.equals("")
       && (str.charAt(str.length() - 1) == s.charAt(i))) {
     builder.deleteCharAt(str.length() - 1);
   } else if (s.charAt(i) != lastchar)
     builder.append(s.charAt(i));
   lastchar = s.charAt(i);
 }
return builder.toString();
}
public静态字符串removedupplicate(字符串s){
StringBuilder=新的StringBuilder();
char lastchar='\0';
对于(int i=0;ipublic static void main(String args[]) {
    System.out.println(removeDuplicate("azxxzy"));
    System.out.println(removeDuplicate("Does this have any duplicates?"));
    System.out.println(removeDuplicate("Nfggfoyy frttrfihht dfbllbfoedssssdsnpr''rp'tuiiu"));
}
public static String removeDuplicate(String s) {
 StringBuilder builder = new StringBuilder();
 char lastchar = '\0';
 for (int i = 0; i < s.length(); i++) {
   String str = builder.toString();
   if (!str.equals("")
       && (str.charAt(str.length() - 1) == s.charAt(i))) {
     builder.deleteCharAt(str.length() - 1);
   } else if (s.charAt(i) != lastchar)
     builder.append(s.charAt(i));
   lastchar = s.charAt(i);
 }
return builder.toString();
}
public static String removeDuplicates(String s) {
if (s.isEmpty()) {
    return s;
}
char[] buf = s.toCharArray();
char lastchar = buf[0];

// i: index of input char
// o: index of output char
int o = 1;
for (int i = 1; i < buf.length; i++) {
    if (o > 0 && buf[i] == buf[o - 1]) {
        lastchar = buf[o - 1];
        while (o > 0 && buf[o - 1] == lastchar) {
            o--;
        }
    } else if (buf[i] == lastchar) {
        // Don't copy to output
    } else {
        buf[o++] = buf[i];
    }
}
return new String(buf, 0, o);
}
 public class StackDemo {
    public static void main(String[] args) throws Exception {
        CharStackArray stack = new CharStackArray(15);
        char[] dupliactes = { 'a', 'z', 'x', 'x', 'z', 'y' };
        stack.removeAdjacentDuplicate(dupliactes);
    }

}

class CharStackArray {
    private char[] array;
    private int top;
    private int capacity;

    public void removeAdjacentDuplicate(char[] arr) throws Exception {
        for (int i = 0; i < arr.length; i++) {
            if (isEmpty()) { // if stack is empty
                push(arr[i]);
                display();
                System.out.println();
            } else {
                int count = 0;
                int j = i;
                /*
                 * while top of stack is equal to next value in array (ie same
                 * adjacent values)
                 */
                while (j < arr.length && peek() == arr[j]) {
                    count++; // count of same occurences
                    j++;
                }
                if (count == 0) { // no same occurence
                    push(arr[i]); // push to stack
                    display();
                    System.out.println();
                } else {
                    for (int k = 1; k < count; k++) // skip the array index for
                        // same adjacent duplicates
                        i++;
                    pop(); // pop the duplicate value from stack
                    display();
                    System.out.println();

                }
            }

        }
    }

    public CharStackArray(int cap) {
        capacity = cap;
        array = new char[capacity];
        top = -1;
    }

    public void push(char data) {
        array[++top] = data;
    }

    public char pop() throws Exception {
        return array[top--];
    }

    public void display() {
        for (int i = 0; i <= top; i++) {
            System.out.print(array[i] + "->");
        }
    }

    public char peek() throws Exception {
        return array[top];
    }

    public boolean isEmpty() {
        return (top == -1);
    }

}
public class RemoveAdjucentDuplicates {
public static void main(String[] args) {
    String s = "azxxzy";
    s = "geeksforgeeg";
    System.out.println(remove(s));
}

static String remove(String s) {
    char res[] = new char[s.length()];
    int j = 0;
    res[j] = s.charAt(0);
    for (int i = 1; i < s.length(); i++) {
        if (s.charAt(i) != res[j]) {
            res[++j] = s.charAt(i);
        } else {
            res[j--] = '\u0000';
        }
    }

    String result = String.valueOf(res);
    return result.substring(0,j+1);
}
}
public class RemoveAdjacant
{
 public String replaceAdjacent(String s)
 {
  if (s.equals(""))
   return s;
  String adjacentString = "";
  char cha;
  int count = 1;
  for (int i = 0; i < s.length(); i++)
  {
   cha = s.charAt(i);
   adjacentString = adjacentString + cha;
   for (int j = 1 + i; j < s.length(); j++)
   {
    if (cha == s.charAt(j))
    {
     adjacentString = adjacentString + cha;
     count++;
    } else
    {
     if (count >= 3)
      break;
     else
     {
      count = 1;
      adjacentString = "";
      break;
     }
    }
   }
   if (count >= 3)
   {
    int index = s.indexOf(adjacentString);
    s = s.substring(0, index)
      + s.substring(index + adjacentString.length());
    return replaceAdjacent(s);
   }
  }
  return s;
 }
 public static void main(String[] args)
 {
  RemoveAdjacant ra = new RemoveAdjacant();
  Scanner scan = new Scanner(System.in);
  System.out.println("Enter string");
  String s = scan.nextLine();
  System.out.println("rem string=" + ra.replaceAdjacent(s));
 }
}
 import java.io.*;
    import java.util.*;
    import java.util.concurrent.TimeUnit;
    import com.google.common.base.Stopwatch;

    /*
     "Given a string, remove the consecutive character pairs repetitively.
    input: saabbs , output : 
    input: aaabbbccc , output : abc"

     */

    class Solution {
      public static String removeDuplicates(String s) {
        int count=0;
        String sout = "";
        if (s.isEmpty() || s.length()==1) {
            return s;
        }
        else{
          s=s+" ";
          for(int i=0; i<s.length()-1;i++){
            if(s.charAt(i)!= s.charAt(i+1) || s.charAt(i+1)==' '){
              sout = sout+s.charAt(i);
            }else{
              count++;
              i=i+1;
            }
          }
        }
        //int count=0;
        for(int i=0; i<sout.length()-1;i++){
          if(sout.charAt(i)==sout.charAt(i+1))
            count++;
        }
        if(count>0){
          return removeDuplicates(sout);
        }else
          return sout;
    }
      public static void main(String[] args) throws IOException{

        Stopwatch timer = Stopwatch.createStarted();
       // String s = "saabbs";
      String s1 = "aaabbbccc";
      //System.out.println("Output1:\t"+removeDuplicates(s));
      System.out.println("Output2:\t"+removeDuplicates(s1));
        timer.stop();
         System.out.printf("Time taken: %,10d microseconds\n", timer.elapsed(TimeUnit.MICROSECONDS));

      }

    }
package algorithms;

public class Sample {

    public static void main(String args[]){
        new Sample().fix("Whaaaatupducck");
    }

    public void fix(String input){
        StringBuilder sb = new StringBuilder();

        for(int index = 0; index<input.length()-1 ;index++){

            System.out.println("compare "+ 
            input.charAt(index)+                
            " and "+
            input.charAt(index+1));

            if(input.charAt(index) == input.charAt(index+1)){
                continue; // skipping repeats
            }else{
                sb.append(input.charAt(index));
            }

            if((index+2) == input.length()){
                sb.append(input.charAt(index+1)); // handling last character
            }
        }
        System.out.println("Result : "+sb.toString());
    }
}
def rmv(st,i):
    if i==len(st)-1:
        return
    if not st:
        return 
    if st[i]==st[i+1]:
        tmp=st[i]
        while(i<len(st) and st[i]==tmp):
            st.pop(i)
        if not i-1:
            rmv(st,i-1)
        else:
            rmv(st,0)
    else:
        rmv(st,i+1)

inp=list("azxxzy")
rmv(inp,0)
print ''.join(inp)
private static String remove(String str1) {
    StringBuilder sb = new StringBuilder();
    Stack<Character> stack = new Stack<Character>();
    stack.push(str1.charAt(0));
    int inx = 1;
    char lastDeleted = '\0';
    while(!stack.isEmpty() && inx < str1.length()){
        if(str1.charAt(inx) == stack.peek()) {
            //repeating character found..
            lastDeleted = stack.pop();
        }else if(str1.charAt(inx) == lastDeleted) {
            //repeating character found but already removed from the stack.
        }else {
            //when a new character is introduced..
            stack.push(str1.charAt(inx));
        }
        inx++;
        if(stack.isEmpty() && inx < str1.length()) {
            //if stack is empty, then insert at least one element if present..
            stack.push(str1.charAt(inx));
            inx++;
        }
    }
    if(stack.isEmpty()) {
        return "";
    }else {
        while(!stack.isEmpty()) {
            sb.insert(0, stack.pop());
        }
    }
    return sb.toString();
}
    public class RemoveAdjacentDuplicates {

        public static void main(String[] args) {
            System.out.println(removeDuplicates("azxxzy"));
        }

         public static String removeDuplicates(String S) {
             char[] stack = new char[S.length()];

             int i = 0;

             for(int j = 0 ; j < S.length() ; j++) {

                 char currentChar = S.charAt(j);
                 if(i > 0 && stack[i-1] == currentChar) {
                     i--;
                 }else {
                     stack[i] = currentChar;
                     i++;
                 }

             }
             return new String(stack , 0 , i);
         }

    }
    input - "azxxzy" 
    output - "ay"
   public static void removeDuplicates(String str)
     {
         if(str.length()<=1)
         {
             System.out.println(str);
             return;
         }
         String n=new String();
         int count=0;
         for(int i=0;i<str.length();i++)
         {
             while(i<str.length()-1 && str.charAt(i)==str.charAt(i+1))
             {
                 if(i<str.length()-2 && str.charAt(i)!=str.charAt(i+2))
                    i+=2;
                 else
                    i++;
                 count++;
             }
             if(i!=str.length()-1){
                 n=n+str.charAt(i);
             }
             else if(i==str.length()-1 && str.charAt(i)!=str.charAt(i-1)){
                 n=n+str.charAt(i);
             }
         }
         if(count>0)
         removeDuplicates(n);
         else
         System.out.println(n);
     }
}
Input: acaaabbbacdddd
Output : acac
Input : azxxzy
Output: ay