LeetCode 分类练习(3)—— 指针碰撞

167. Two Sum II - Input array is sorted

Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution and you may not use the same element twice.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

思路:
1、一个指针指向数组的头部,一个指针指向数组的尾部
2、计算两指针指向元素的和
3、如果大于 target,尾指针左移
4、如果小于 target,头指针右移
5、如果等于 target,返回两指针下标 + 1 组成的数组

package com.leetcode.array;

// 167 Two_Sum_II

public class Two_Sum_II {
    public int[] twoSum(int[] numbers, int target) {
        int i = 0;  // 数组头指针
        int j = numbers.length - 1; // 数组尾指针
        while (i < j) { // 两指针相遇之前
            if (numbers[i] + numbers[j] > target)   // 尾指针左移
                j--;
            else if (numbers[i] + numbers[j] < target)  // 头指针右移
                i++;
            else    // numbers[i] + numbers[j] == target 跳出循环
                break;
        }
        return new int[]{i + 1, j + 1};
    }

    public static void main(String[] args) {
//        Input: numbers={2, 7, 11, 15}, target=9
//        Output: index1=1, index2=2
//        int[] numbers = {2, 7, 11, 15};
//        int target = 9;
        int[] numbers = {2, 7, 11, 15};
        int target = 22;
        Two_Sum_II two_sum_ii = new Two_Sum_II();
        int[] result = two_sum_ii.twoSum(numbers, target);
        for (int k : result)
            System.out.print(k + " ");
    }


}

125. Valid Palindrome

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.

Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.

For the purpose of this problem, we define empty string as valid palindrome.

这里要注意,题目说的是字母或是数字都算是回文串的一部分

思路:
1、一个指针指向字符串的头部,一个指向尾部
2、若两指针所指向的字符都是 数字或字母,且两者指向的字符相等(忽略大小写),则头指针右移,尾指针左移
3、如果两者指向的字符不等,返回 false
4、如果头指指向的字符不是 字母或者数字,头指针右移
5、反之,尾指针左移
6、重复此过程,直到两指针相遇

package com.leetcode.String;

// 125 Valid_Palindrome

// 题目要求的是字母或是数字!!!
// 字符串为空算是回文串

public class Valid_Palindrome {
    public boolean isPalindrome(String s) {
        if (s.isEmpty()){
            return true;
        }

        int i = 0;
        int j = s.length() - 1;
        char ch_1, ch_2;
        while (i <= j) {
            ch_1 = s.charAt(i);
            ch_2 = s.charAt(j);
            if (Character.isLetterOrDigit(ch_1) && Character.isLetterOrDigit(ch_2)) {
                if (Character.toLowerCase(ch_1) == Character.toLowerCase(ch_2)) {
                    i++;
                    j--;
                } else {
                    return false;
                }
            } else if (Character.isLetterOrDigit(ch_1)) {
                j--;
            } else {
                i++;
            }
        }
        return true;
    }


    public static void main(String[] args) {
        String s = "A man, a plan, a canal: Panama";
        Valid_Palindrome valid_palindrome = new Valid_Palindrome();
        System.out.println(valid_palindrome.isPalindrome(s));

        String k = "race a car";
        System.out.println(valid_palindrome.isPalindrome(k));

        String f = "0P";
        System.out.println(valid_palindrome.isPalindrome(f));

    }

}

344. Reverse String

Write a function that takes a string as input and returns the string reversed.

Example:
Given s = "hello", return "olleh".

思路:
1、设置一个头指针,一个尾指针
2、省略余下步骤…

package com.leetcode.String;

//  344 Reverse_String

public class Reverse_String {
    public String reverseString(String s) {

        StringBuilder strBuilder = new StringBuilder(s);

        int i = 0;
        int j = s.length() - 1;

        while (i < j) {
            strBuilder.setCharAt(i, s.charAt(j));
            strBuilder.setCharAt(j, s.charAt(i));
            i++;
            j--;
        }
        return strBuilder.toString();
    }

    public static void main(String[] args){
        String str = "hello";
        Reverse_String reverse_string = new Reverse_String();
        System.out.println(reverse_string.reverseString(str));
    }
}

345. Reverse Vowels of a String

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

Example 1:
Given s = "hello", return "holle".

Example 2:
Given s = "leetcode", return "leotcede".

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

注意大小写问题!

思路和前几到题一样

package com.leetcode.String;

// 345. Reverse Vowels of a String

import java.util.Arrays;
import java.util.List;

public class Reverse_Vowels_of_a_String {
    public String reverseVowels(String s) {
        if (s.isEmpty() || s.length() == 1)
            return s;

        // 应该考虑大小写问题!
        Character[] vowel_arr = {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'};

        List<Character> vowel_list = Arrays.asList(vowel_arr);
        StringBuilder strBuilder = new StringBuilder(s);

        int i = 0;
        int j = s.length() - 1;
        char ch_1, ch_2;
        while (i <= j) {
            ch_1 = s.charAt(i);
            ch_2 = s.charAt(j);
            if (vowel_list.contains(ch_1) && vowel_list.contains(ch_2)){
                strBuilder.setCharAt(i, s.charAt(j));
                strBuilder.setCharAt(j, s.charAt(i));
                i++;
                j--;
            }else if (vowel_list.contains(ch_1)){
                j--;
            }else {
                i++;
            }
        }
        return strBuilder.toString();
    }

    public static void main(String[] args){
        Reverse_Vowels_of_a_String reverse_vowels_of_a_string = new Reverse_Vowels_of_a_String();

        String str =  "hello";
        System.out.println(reverse_vowels_of_a_string.reverseVowels(str));

        String str_1 = "leetcode";
        System.out.println(reverse_vowels_of_a_string.reverseVowels(str_1));


    }

}

11. Container With Most Water

Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container and n is at least 2.

注意题目说的是两边和 x 轴方向上的长度构成的矩形的面积!不要忽略 x 轴方向上的长度!

思路:
1、和 167 题的想法相近,恩

package com.leetcode.array;

import java.util.Arrays;

public class Container_With_Most_Water {
    public int maxArea(int[] height) {
        if (height == null || height.length == 0 || height.length == 1)
            return 0;
        if (height.length == 2)
            return height[0] > height[1] ? height[1] : height[0];

        int i = 0;
        int j = height.length - 1;
        int maxArea = 0;
        while (i < j) {
            maxArea = Math.max(maxArea, Math.min(height[i], height[j]) * (j - i));
            if (height[i] > height[j])
                j--;
            else
                i++;
        }
        return maxArea;
    }

    // 题意理解错误!!! 不仅是两个边的高度,还要考虑 x 轴方向上的长度!!
    // 所以应该用双指针对撞方式求解
//    public int maxArea(int[] height) {
//        if (height == null || height.length == 0 || height.length == 1)
//            return 0;
//        if (height.length == 2)
//            return height[0] > height[1] ? height[1] : height[0];
//
//        int target = 1;
//        return solve(height, 0, height.length - 1, target);
//    }
//
//    public int solve(int[] arr, int l, int r, int target) {
//        int p = partition(arr, l, r);
//        if (p > target)
//            return solve(arr, l, p - 1, target);
//        else if (p < target)
//            return solve(arr, p + 1, r, target);
//        else
//            return arr[p];
//
//    }
//
//    public int partition(int[] arr, int l, int r) {
//        swap(arr, l, (int) (Math.random() * (r - l + 1) + l));
//        int temp = arr[l];
//        int i = l + 1, j = l;
//        for (; i <= r; i++) {
//            if (arr[i] > temp)
//                swap(arr, i, ++j);
//        }
//        swap(arr, l, j);
//        return j;
//    }
//
//    public void swap(int[] arr, int i, int j) {
//        int temp = arr[i];
//        arr[i] = arr[j];
//        arr[j] = temp;
//    }

    public static void main(String[] args) {
        Container_With_Most_Water container_with_most_water = new Container_With_Most_Water();

        int[] height = {1, 2, 3, 2, 2, 2, 3, 45, 6, 4, 3, 3, 2, 43, 5, 3, 2};

//        int[] height = {1, 2, 3};


        System.out.println(container_with_most_water.maxArea(height));

    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值