程序员面试金典:翻转子串、链表中倒数第k个结点

1.翻转子串

题目描述

假定我们都知道非常高效的算法来检查一个单词是否为其他字符串的子串。请将这个算法编写成一个函数,给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成,要求只能调用一次检查子串的函数。

给定两个字符串s1,s2,请返回bool值代表s2是否由s1旋转而成。字符串中字符为英文字母和空格,区分大小写,字符串长度小于等于1000。

测试样例:

"Hello world","worldhello "
返回:false
"waterbottle","erbottlewat"
返回:true

解法1:将两个字符串变成char数组,然后再进行排序,最后用equals方法比较两个字符数组

import java.util.*;

public class ReverseEqual {
    public boolean checkReverseEqual(String s1, String s2) {
        if(s1.length()!=s2.length())	return false;
        char []ch1=s1.toCharArray();
        char []ch2=s2.toCharArray();
        Arrays.sort(ch1);
        Arrays.sort(ch2);
        if(Arrays.equals(ch1,ch2))
            return true;
        return false;
    }
}

解法2:将两个字符串变成char数组,排序然后挨个比较是否相等

import java.util.*;

public class ReverseEqual {
    public boolean checkReverseEqual(String s1, String s2) {
        if(s1.length()!=s2.length())	return false;
    	char ch1[]=s1.toCharArray();	
    	char ch2[]=s2.toCharArray();
    	
    	Arrays.sort(ch1);
    	Arrays.sort(ch2);
    	
    	for (int i = 0; i < ch2.length; i++) {
			if(ch1[i]!=ch2[i]){
				return false;
			}
		}
    	return true;
    }
}

解法3:通过两个字符串拼接,然后看看这个字符串是否包含其中的单个字符串

import java.util.*;

public class ReverseEqual {
    public boolean checkReverseEqual(String s1, String s2) {
        String str=s1+s1;
    	return str.contains(s2);
    }
}

解法4:用两个int数组分别统计两个字符串中字母的个数是否相等。

import java.util.*;

public class ReverseEqual {
    public boolean checkReverseEqual(String s1, String s2) {
        // write code here
        
    	if(s1.length()!=s2.length())	return false;
    	byte arr1[]=new byte[128];
    	byte arr2[]=new byte[128];
    	
    	for (int i = 0; i < s1.length(); i++) {
			arr1[s1.charAt(i)]++;
			arr2[s2.charAt(i)]++;
		}
    	
    	for (int i = 0; i < arr2.length; i++) {
			if(arr1[i]!=arr2[i])
				return false;
		}
    	return true;
    }
}

2.链表中倒数第k个结点

题目描述

输入一个链表,输出该链表中倒数第k个结点。

方法1:找到倒数第k个节点,返回其头节点

public class Main{
	public static void main(String[] args) {
		//链表:1->3->5->8->6->5		k=2
		ListNode t1=new ListNode(1);
		ListNode t2=new ListNode(3);
		ListNode t3=new ListNode(5);
		ListNode t4=new ListNode(8);
		ListNode t5=new ListNode(6);
		ListNode t6=new ListNode(5);
		
		t1.next=t2;
		t2.next=t3;
		t3.next=t4;
		t4.next=t5;
		t5.next=t6;
		
		ListNode tt=FindKthToTail(t1, 2);
		while(tt!=null){
			System.out.print(tt.val+"->");
			tt=tt.next;
		}
	}
	
	public static ListNode FindKthToTail(ListNode head,int k) {
		 	ListNode node = head;
	        if(node==null) return null;
			int length=0;
	    	while(node!=null){
	    		node=node.next;
	    		length++;
	    	}
	    	
	        if(k>length) return null;
	        ListNode list=head;
	        for(int i=0;i<length-k;i++){
	            list=list.next;
	        }
	    	return list;
	}
}

方法2:用两个指针,一个先移k个,然后让第二个移动,当第一个移到结尾时,第二个就移到倒数第k个节点了

import util.java.Algorithm.ListNode;

public class Main{
	public static void main(String[] args) {
		//链表:1->3->5->8->6->5		k=2
		ListNode t1=new ListNode(1);
		ListNode t2=new ListNode(3);
		ListNode t3=new ListNode(5);
		ListNode t4=new ListNode(8);
		ListNode t5=new ListNode(6);
		ListNode t6=new ListNode(5);
		
		t1.next=t2;
		t2.next=t3;
		t3.next=t4;
		t4.next=t5;
		t5.next=t6;
		
		ListNode tt=FindKthToTail(t1, 2);
		while(tt!=null){
			System.out.print(tt.val+"->");
			tt=tt.next;
		}
	}
	
	public static ListNode FindKthToTail(ListNode head,int k) {
		ListNode p=head;
		ListNode pre=head;
		
		int a=k;
		int count=0;
		while(p!=null){
			p=p.next;
			count++;
			if(k<=0){
				pre=pre.next;
			}
			k--;
		}
		
		if(count<a)	return null;
		return pre;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值