LeetCode刷题之双指针

345. Reverse Vowels of a String (翻转字符串中的元音)

Write a function that takes a string as input and reverse only the vowels of a string.java

Example 1:数组

Input: "hello"
Output: "holle"app

Example 2:spa

Input: "leetcode"
Output: "leotcede"指针

Note: The vowels does not include the letter "y".code

这道题的意思是让咱们交换首尾对应的元音,元音包括大小写一共有10个(a,e,i,o,u,A,E,I,O,U),能够写个判断是否为元音的方法,遍历字符串,当left和right都为元音时交换,若是left是元音,则right--,若是right是元音,left++。orm

解法一:(最后显示超出时间限制)排序

public class Solution {
    public String reverseVowels(String s) {
        if (s == null){
            return null;
        }
        char[] chars = s.toCharArray();
        int left = 0;
        int right = chars.length - 1;
        while (left <= right){
            //若是两个恰好都是元音,交换
            if (isVowel(chars[left]) && isVowel(chars[right])){
                swap(chars, left, right);
            }else if(isVowel(chars[left])){
                //左边是元音,停下,右边移动
                right--;
            }else {
                left++;
            }
        }
        return chars.toString();
    }

    //交换元音
    public void swap(char[] chars, int left, int right){
        char tmp = chars[left];
        chars[left] = chars[right];
        chars[right]  = tmp;
    }

    //判断是否为元音
    public boolean isVowel(char c){
        HashSet<Character> set = new HashSet<Character>(Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));
        return set.contains(c);
    }
}
复制代码
将数组交换换成新建数组进行填充以后问题获得解决
class Solution {
    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) {
        if (s == null) return null;
        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);
    }
}
复制代码

680. Valid Palindrome II (判断字符串是否为回文结构)

Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome.ci

Example 1:element

Input: "aba"
Output: True

Example 2:

Input: "abca"
Output: True

Explanation: You could delete the character 'c'.
Note:
The string will only contain lowercase characters a-z. The maximum length of the string is 50000.

题意是判断字符串是否为回文字结构,而且能够删除一个字符,那么就能够用两个指针start、end从头和尾一块儿开始判断,遇到相同的就直接跳过,遇到不一样时就删除,关键在于删除能够删start或者end对应的字符,就是说有两种状况,那么两种状况都尝试

class Solution {
    public boolean validPalindrome(String s) {
        //定义两个指针
        int start = 0;
        int end = s.length() - 1;
        for(start = 0, end = s.length() - 1; start <= end; start++, end--){
            if(s.charAt(start) != s.charAt(end)){
                //删除左边字符或者右边字符
                return valid(s,start + 1, end) || valid(s,start, end - 1);
            }
            
        }
        return true;
    }
    
    private boolean valid(String s, int start, int end){
        while(start <= end){
            if(s.charAt(start++) != s.charAt(end--)){
                return false;
            }
        }
        return true;
    }
}
复制代码

88. Merge Sorted Array(归并两个已排序的数组)

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:

The number of elements initialized in nums1 and nums2 are m and n respectively.
You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2.

Example:

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

题意是给定两个数组nums1和nums2,两个初始化参数m、n表示数组中初始化的元素个数,能够假设nums1有足够的空间。若是从nums1头部开始归并,会覆盖掉后面未排序的元素,因此采用从后面归并的方式。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        //准备两个指针
        int index1 = m - 1;
        int index2 = n - 1;
        int mergeIndex = m + n - 1;
        
        while(index1 >= 0 && index2 >= 0){
            if(index1 < 0){
                //若是nums1先归并完
                nums1[mergeIndex--] = nums2[index2--];
            }else if(index2 < 0){
                //若是nums2先归并完
                nums1[mergeIndex--] = nums1[index1--];
            }else if(nums1[index1] > nums2[index2]){
                nums1[mergeIndex--] = nums1[index1--];
            }else{
                nums1[mergeIndex--] = nums2[index2--];
            }
        }
    }
}
复制代码

141. Linked List Cycle(判断单链表是否有环)

Given a linked list, determine if it has a cycle in it.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

题意大概是给你一个单链表,而后让你判断这个链表是否有环,首先能够想到的第一种解法是准备一个set,遍历到一个就存储一个,而后检查set里面有无重复的。第二种方法是用快慢指针,快指针一次走一=两步,慢指针一次走一步,若是慢指针走到最后都没相遇,那么就无环,不然有环

/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head == null){
            return false;
        }
        ListNode fast = head.next;
        ListNode slow = head;
        while(fast != null && slow != null && fast.next != null){
            if(fast == slow){
                return true;
            }
            fast = fast.next.next;
            slow = slow.next;
        }
        return false;
    }
}
复制代码

524. Longest Word in Dictionary through Deleting (最长子序列)

Given a string and a string dictionary, find the longest string in the dictionary that can be formed by deleting some characters of the given string. If there are more than one possible results, return the longest word with the smallest lexicographical order. If there is no possible result, return the empty string.

Example 1:

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

Example 2:

Input:
s = "abpcplea", d = ["a","b","c"]
Output:
"a"

Note:

  1. All the strings in the input will only contain lower-case letters.
  2. The size of the dictionary won't exceed 1,000.
  3. The length of all the strings in the input won't exceed 1,000.

题意:删除 s 中的一些字符,使得它构成字符串列表d中的一个字符串,找出能构成的最长字符串。若是有多个相同长度的结果,返回字典序的最小字符串。
经过删除字符串 s 中的一个字符能获得字符串t是s的子序列,咱们能够使用双指针来判断一个字符串是否为另外一个字符串的子序列。

class Solution {
    public String findLongestWord(String s, List<String> d) {
        String result = "";
        //遍历给定字符串数组
        for(String w : d){
            int len1 = result.length();
            int len2 = w.length();
            //若是result的长度大于w,或者长度相等,可是result字典序比较小,不更新result
            if(len1 > len2 || (len1 == len2 && result.compareTo(w) < 0)){
                continue;
            }
            if(isSub(s, w)){
                result = w;
            }
        }
        return result;
    }
    
    private boolean isSub(String s, String w){
        int i = 0; //s的指针
        int j = 0; //w的指针
        while (i < s.length() && j < target.length()) {
            if(s.charAt(i) == w.charAt(j)){
                j++;
            }
            i++;
        }
        return j == w.length();
    }
复制代码
相关文章
相关标签/搜索