剑指offer--42.翻转单词顺序VS左旋字符串

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:54   1368   0

题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变,为简单起见,标点符号和普通字母一样处理,eg,输入str="I am a student."输出为"student. a am I"

分析:第一步翻转句子的所有字符,第二步翻转每个单词的字符

题目二:字符串的左旋转操作,是把字符串前面的若干个字符转移到字符串的尾部,eg,输入"abcdefg"和数字2,返回左旋2位得到"cdefgab"

分析:把字符串分为两部分即“ab”“cdefg”,先分别翻转这两部分,即"bagfedc",再翻转整个字符串得到"cdefgab"

public class wr42Reverse {
 public static String ReverseSentence(String str){
  if(str.length()==0){
   return "";
  }
  char[] chars=str.toCharArray();
//  翻转整个句子
  reverse(chars,0,chars.length-1);
  int start=0;
//  翻转句中的每个单词
  for(int i=0;i<chars.length;i++){
   if(chars[i]==' '){
    reverse(chars,start,i-1);
    start=i+1;
   }
  }
//  最后一个单词后无空格,做特殊处理
  reverse(chars,start,chars.length-1);
  return String.valueOf(chars);
 }
// 翻转字符串中的一段
 public static void reverse(char[]chars,int low,int high){
  while(low<high){
   char temp=chars[low];
   chars[low]=chars[high];
   chars[high]=temp;
   low++;
   high--;
  }
 }
 
 public static String LeftRotateString(String str,int n) {
  if(str==null || n<0 || n>str.length()){
   return "";
  }

  char[] chars=str.toCharArray();
  reverse(chars,0,n-1);
  reverse(chars,n,chars.length-1);
  reverse(chars,0,chars.length-1);
  return String.valueOf(chars);
 } 
 
 public static void main(String []args){
  String str="I am a student.";
  System.out.println(ReverseSentence(str));
  
  String strRotate="abcdefg";
  System.out.println(LeftRotateString(strRotate,2));
 }
}

该题型让我想起之前看过的程序员面试宝典上的一道题:

题目三:数组循环右移k位,假设要把数组序列12345678循环右移2位得到78123456

分析:和上述思想一致,将数组序列分为两个部分,先逆序子序列123456变为654321,再逆序子序列78变为87,最后对65432187全部逆序即可得到78123456

public class wr42ReverseShift {
    public static void reverse(int [] a,int b,int e){
        for(;b<e;b++,e--){
            int temp=a[e];
            a[e]=a[b];
            a[b]=temp;
        }
    }

    public static void shift_k(int []a,int k){
        int n=a.length;
        k=k%n;//为了防止k比n大,右移k为和右移k%n结果是一样的
        reverse(a,n-k,n-1);
        reverse(a,0,n-k-1);
        reverse(a,0,n-1);
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int array[]={1,2,3,4,5,6,7,8};
        shift_k(array,2);
        for(int i:array){
            System.out.print(i+" ");
        }

    }

}

联想到LeetCode上有道题,,

题目四:给定一个链表,将链表向右旋转k个位置,其中k为非负数,eg:

Given1->2->3->4->5->NULLand k =2,

return4->5->1->2->3->NULL

public static ListNode test(ListNode head,int k){
        if(k==0 || head==null || head.next==null){
            return head;
        }
        ListNode preHead=new ListNode(0);
        preHead.next=head;
        ListNode cur=head;
        ListNode pre=head;
        int total=0;
        for(total=1;cur.next!=null;total++){//求出链表长度
            cur=cur.next;
        }
        for(int i=1;i<total-k%total;i++){//向前走length-n
            pre=pre.next;
        }
        cur.next=preHead.next;
        preHead.next=pre.next;
        pre.next=null;
        return preHead.next;
    }

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP