推免机试练习1(双指针)

双指针
题目介绍

public int[] twoSum(int[] numbers, int target) {
	int i = 0, j = numbers.length - 1;
	while (i < j) {
		int sum = numbers[i] + numbers[j];
		if (sum == target) {
			return new int[] {i + 1, j + 1};
		}
		else if (sum < target) {
			i++;
		}
		else {
			j--;
		}
	}
	return null;
}

2.两数平方和

Input: 5
Output: True
Explanation: 1 * 1 + 2 * 2 = 5

题目描述:判断一个数是否为两个数的平方和。

public boolean judgeSquareSum(int c) {
    int i = 0, j = (int) Math.sqrt(c);
    while (i <= j) {
        int powSum = i * i + j * j;
        if (powSum == c) {
            return true;
        } else if (powSum > c) {
            j--;
        } else {
            i++;
        }
    }
    return false;
}

3.反转字符串中的元音字符

Given s = "leetcode", return "leotcede".

使用双指针指向待反转的两个元音字符,一个指针从头向尾遍历,一个指针从尾到头遍历。

private final static HashSet<Character> vowels=new HashSet<>(Arrays.asList('a','e','i','o','u','A','E','I','O','U'));

public String reverseVowels(String s){
int i=0,j=s.length()-1;
char[] result=new char[s.length()] ;
while(i<=j){
char ci=s.charAt(i);
char cj=s.charAt(j);
if(!vowels.contains(ci)){
result[i++]=ci;}
else if(!vowels.contains(cj)){
result[j--]=cj;
}else{
result[i++]=cj;
result[j--]=ci;
}
}
return new String(result);
}

4.回文字符串

Input: "abca"
Output: True
Explanation: You could delete the character 'c'.

题目描述:可以删除一个字符,判断是否能构成回文字符串。

public boolean validPalindrome(String s){
for(int i=0;j=s.length()-1;i<j;i++,j--){
if(s.charAt(i)!=s.char(j)){
return isPalindrome(s,i,j-1)||isPalindrome(s,i+1,j);
}
}
return true;
}

private boolean isPalindrome(String s,int i,int j){
while(i<j){
if(s.charAt(i++)!=s.charAt(j--)){
return false;
}
}
return true;
}

5.归并两个有序数组

Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3

Output: [1,2,2,3,5,6]

题目描述:把归并结果存到第一个数组中。
需要从尾开始遍历,否则在nums1上归并得到的值会覆盖还未进行归并比较的值。

public void merge(int[] nums1,int m,int[] nums2,int n){
int index1=m-1,index2=n-1;
int indexMerge=m+n-1;
while(index1>=0||index2>=0){
if(index1<0){
nums1[indexMerge--]=nums2[index2--];
}else if(index2<0){
nums1[indexMerge--]=nums1[index1--];
}else if(nums1[index1]>nums2[index2]){
num1[indexMerge--]=nums1[index1--];
}else{
nums1[indexMerge--]=nums[index2--];
}
}
}


6.判断链表是否存在环
使用双指针,一个指针每次移动一个节点,一个指针每次移动两个节点,如果存在环,那么这两个指针一定相遇。

public boolean hasCycle(ListNode head){
if(head==null){
return false;
}
ListNode L1=head;L2=head.next;
while(L1!=null&&L2!=null&&L2.next!=null){
if(L1==L2){
return true;
}
L1=L1.next;
L2=L2.next.next;
}
return false;
}

7.最长子序列

Input:
s = "abpcplea", d = ["ale","apple","monkey","plea"]

Output:
"apple"

题目描述:删除s中的一些字符,使它构成字符串列表d中的一个字符串,找出能构成最长的字符串。如果有多个相同长度的结果,返回字典序的最小字符串。

通过删除字符串s中的一个字符能得到字符串t,可以认为t是s的子序列,可以使用双指针来判断一个字符串是否为另一个字符串的子序列。

public String finalLongestWord(String s,List<String> d){
String longestWord="";
for(String target:d){
int L1=longestWord.length(),L2=target.length();
if(L1>L2||(L1==L2&&longestWord.compareTo(target)<0)){
continue;
}
if(isSubstr(s,target)){
longestWord=target;
}
}
return longestWOrd;
}

private boolean isSubstr(String s,String target){
int i=0;j=0;
while(i<s.length()&&j<target.length()){
if(s.charAt(i)==target.charAt(j)){
j++;}
i++;
}
return j==target.length();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值