Rearrange Characters in String With No Adjacent Duplicate Characters


Related: LeetCode 767 - Reorganize String
Rearrange Characters in String With No Adjacent Duplicate Characters - Algorithms and Problem SolvingAlgorithms and Problem Solving
Given a string, rearrange characters of the string such that no duplicate characters are adjacent to each other.
In order to implement the above idea we can maintain a MaxHeap of character frequency histogram. Each time we try to extract two top most frequent characters and place them in adjacent positions. Then we add those characters back to the heap with decreased frequency (why?). This way we guarantee that the arrangement doesn’t have any two repeating element in adjacent places. The following implementation is based on using PriorityQueue for max heap. Time complexity is O(n) to build the initial heap and O(nlgn) to update the heap for each pair of character realignment.

public static String rearrangeAdjacentDuplicates(String str){
 final class CharFreq implements Comparable<CharFreq>{
  char c;
  int freq;
  public CharFreq(char ch, int count){
   c = ch;
   freq = count;
  }
  @Override
  public int compareTo(CharFreq o) {
   int comp = Double.compare(freq, o.freq);
   if(comp == 0){
    comp = Character.compare(o.c, c);
   }
   
   return comp;
  }
 }
 
 int n = str.length();
 StringBuffer rearranged = new StringBuffer();
 PriorityQueue<CharFreq> maxHeap = new PriorityQueue<CharFreq>(256, Collections.reverseOrder());
 int freqHistoGram[] = new int[256];
 //build the character frequency histogram
 for(char c : str.toCharArray()){
  freqHistoGram[c]++;
  
  //if a character repeats more than n/2 then we can't rearrange
  if(freqHistoGram[c] > (n+1)/2){
   return str; // throe ex;
  }
 }
 //build the max heap of histogram
 for(char i  = 0; i < 256; i++){
  if(freqHistoGram[i] > 0)
   maxHeap.add(new CharFreq(i, freqHistoGram[i]));
 }
 
 //rearrange - pop top 2 most frequent items and arrange them in adjacent positions
 //decrease the histogram frequency of the selected chars 
 while(!maxHeap.isEmpty()){
  //extract top one and decrease the hstogram by one
  CharFreq first = maxHeap.poll();
  rearranged.append(first.c);
  first.freq--;
  
  CharFreq second = null;
  //extract second top and decrease the histogram by one
  if(!maxHeap.isEmpty()){
   second = maxHeap.poll();
   rearranged.append(second.c);
   second.freq--;
  }
  
  //add back the updated histograms 
  if(first.freq > 0){
   maxHeap.add(first);
  }
  if(second != null && second.freq > 0){
   maxHeap.add(second);
  }
 }
 
 return rearranged.toString();
}
https://gist.github.com/gcrfelix/672a4c7952c02e57aee5
题目大致是BACCBBAAA -> ABABACABC,就是输出相邻字母不能相同的string

解题思路:建立一个maxHeap,按char在string里出现的次数存char,然后不断pop后再加入heap中重新排序,就是每次把出现次数最多的字母先解决

public class Solution {
  public String rearrangeString(String s) {
    HashMap<Character, Integer> map = new HashMap<Character, Integer>();
    for(int i=0; i<s.length(); i++) {
      char c = s.charAt(i);
      if(map.containsKey(c)) {
        map.put(c, map.get(c)+1);
      } else {
        map.put(c, 1);
      }
    }
 
    PriorityQueue<Element> maxHeap = new PriorityQueue<Element>(1, new Comparator<Element>() {
      public int compare(Element e1, Element e2) {
        return e2.count - e1.count;
      }
    });
 
    for(char c : map.keySet()) {
      int count = map.get(c);
      Element e = new Element(c, count);
      maxHeap.offer(e);
    }
 
    StringBuilder sb = new StringBuilder();
    while(!maxHeap.isEmpty()) {
      Element e1 = maxHeap.poll();
      if(maxHeap.isEmpty()) {   // maxHeap里还有最后一个char时的处理办法
        sb.append(e1.c);
        break;
      }
      Element e2 = maxHeap.poll();
      sb.append(e1.c);
      sb.append(e2.c); // this work???
      if(e1.count > 1) {
        e1.count --;
        maxHeap.offer(e1);
      }
      if(e2.count > 1) {
        e2.count --;
        maxHeap.offer(e2);
      }
    }
    return sb.toString();
  }
}

http://www.geeksforgeeks.org/rearrange-characters-string-no-two-adjacent/
Given a string with repeated characters, task is rearrange characters in a string so that no two adjacent characters are same.
The idea is to put highest frequency character first (a greedy approach). We use a priority queue (Or Binary Max Heap) and put all characters and ordered by their frequencies (highest frequency character at root). We one by one take highest frequency character from the heap and add it to result. After we add, we decrease frequency of the character and we temporarily move this character out of priority queue so that it is not picked next time.
Time complexity : O(n log n)
void rearrangeString(string str)
{
    int n = str.length();
    // Store frequencies of all characters in string
    int count[MAX_CHAR] = {0};
    for (int i = 0 ; i < n ; i++)
        count[str[i]-'a']++;
    // Insert all characters with their frequencies
    // into a priority_queue
    priority_queue< Key > pq;
    for (char c = 'a' ; c <= 'z' ; c++)
        if (count[c-'a'])
            pq.push( Key { count[c-'a'], c} );
    // 'str' that will store resultant value
    str = "" ;
    // work as the previous visited element
    // initial previous element be. ( '#' and
    // it's frequency '-1' )
    Key prev {-1, '#'} ;
    // traverse queue
    while (!pq.empty())
    {
        // pop top element from queue and add it
        // to string.
        Key k = pq.top();
        pq.pop();
        str = str + k.ch;
        // IF frequency of previous character is less
        // than zero that means it is useless, we
        // need not to push it
        if (prev.freq > 0)
            pq.push(prev);
        // make current character as the previous 'char'
        // decrease frequency by 'one'
        (k.freq)--;
        prev = k;
    }
    // If length of the resultant string and original
    // string is not same then string is not valid
    if (n != str.length())
        cout << " Not valid String " << endl;
    else // valid string
        cout << str << endl;
}
Read full article from Rearrange Characters in String With No Adjacent Duplicate Characters - Algorithms and Problem SolvingAlgorithms and Problem Solving

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts