• "Coding Interview Guide" -- 翻转字符串


    题目

      给定一个字符类型的数组chas,请在单词间做逆序调整。只要做到单词顺序逆序即可,对空格的位置没有特别要求

      举例,如果把chas看作字符串为"dog loves pig",调整成"pig loves dog";如果把chas看作字符串为"I'm a student.",调整成"student. a I'm"

    要求

      如果chas长度为N,要求时间复杂度为O(N),空间复杂度为O(1)

    分析

      首先将整个单词序列逆序,逆序后再将每个单词逆序,即可将单词顺序逆序。如"dog loves pig",首先将整个单词序列逆序得到"gip sevol god",然后将每个单词逆序,得到"pig loves dog"。整个过程都实在元字符数组的基础上完成的,所以空间复杂的为O(1),全程总共只遍历了整个字符数组两次,所以时间复杂度为O(N)  

     1 public void rotateWord(char[] chas)
     2 {
     3     if(chas == null || chas.length == 0)
     4     {
     5         return;
     6     }
     7 
     8     reverse(chas, 0, chas.length -1);      // 先将整个单词序列逆序
     9     int left = -1;         // left跟踪单词的左边界
    10     int right = -1;        // right跟踪单词的右边界
    11     for(int i = 0; i < chas.length; i++)
    12     {
    13       if(chas[i] != ' ')
    14       {
    15           left = i == 0 || chas[i-1] == ' ' ? i : left;    
    16           right = i == chas.length || chas[i+1] == ' ' ? i : right;
    17       }
    18       if(left != -1 && right != -1)         
    19       {
    20           reverse(chas, left, right);        // 然后将单个单词逆序
    21           left = -1;
    22           right = -1;
    23       }
    24 
    25     }
    26 }
    27                 
    28             
    29 public void reverse(char[] chas, int start, int end)
    30 {
    31     char temp;
    32         
    33     while(start < end)
    34     {
    35       temp = chas[start];
    36       chas[start] = chas[end];
    37       chas[end] = temp;
    38       start++;
    39         end--;
    40     }        
    41 }
    42 
    43     

    题目

      给定一个字符类型的数组chas和一个整数size,请把大小为size的左半区整体移到右半区,右半区整体移到左边

      举例,如果把chas看作字符串为"ABCDE",size=3,调整成"DEABC"

    要求

      如果chas长度为N,要求时间复杂度为O(N),空间复杂度为O(1)

    分析

      可以先将字符数组整体翻转,然后将长度为chas.length-size的左半区和长度为size的右半区分别翻转。或者先将长度为size的左半区逆序,然后将长度为chas.length-size的右半区逆序,最后整体逆序

    方法一:

     1 public void rotate(char[] chas, int size)
     2 {
     3     if(chas == null || chas.length == 0)
     4     {
     5       return;
     6     }
     7     reverse(chas, 0, chas.length-1);           // 先整体逆序
     8     reverse(chas, 0, chas.length-size-1);     // 将翻转后得到的数组中长度为chas.length-size的左半区逆序
     9     reverse(chas, chas.length-size, chas.length-1);  // 长度为size的右半区逆序
    10 }
    11 
    12 public void rotate(char[] chas, int size)
    13 {
    14     if(chas == null || chas.length == 0)
    15     {
    16       return;
    17     }
    18 
    19     reverse(chas, 0, size-1);             // 将长度为size的左半区逆序
    20     reverse(chas, size, arr.length-1);  // 长度为arr.length-size的右半区逆序
    21     reverse(chas, 0, arr.length-1);     // 整体逆序
    22 }

    方法二:

     1 public void rotate(char[] chas, int size)
     2 {
     3    if(chas == null || chas.length < size)
     4     {
     5         return;
     6     }
     7 
     8     int start = 0;
     9     int end = chas.length - 1;
    10     int lpart = size;
    11     int rpart = chas.length - size;
    12     int m = Math.min(lpart, rpart);
    13     int d = lpart - rpart;
    14     while(true)
    15     {
    16         exchange(chas, start, end, m);
    17         if(d == 0)
    18         {
    19             break;
    20         }
    21         else if(d > 0)
    22         {
    23             start += m;
    24             lpart = d;
    25         }
    26         else
    27         {
    28             end -= m;
    29             rpart = -d;
    30         }
    31         m = Math.min(lpart, rpart);
    32         d = lpart - rpart;
    33     }
    34 }
    35 
    36 public void exchange(char[] chas, int start, int end, int size)
    37 {
    38     end = end - size + 1;
    39     char temp = 0;
    40     while(size-- != 0)
    41     {
    42         temp = chas[start];
    43         chas[start] = chas[end];
    44         chas[end] = temp;
    45         start++;
    46         end++;
    47     }
    48 }

    来源:左程云老师《程序员代码面试指南》

  • 相关阅读:
    Robberies
    Big Event in HDU
    UVA 562 Dividing coins
    Little Rooks
    Bone Collector
    Piggy-Bank
    0-1背包问题之——饭卡
    Monkey and Banana
    The Triangle
    Burning Midnight Oil
  • 原文地址:https://www.cnblogs.com/OoycyoO/p/10886242.html
Copyright © 2020-2023  润新知