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

题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变,为简单起见,标点符号和普通字母一样处理,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;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值