leetcode双指针算法

本文将持续更新

 
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
 
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
 
说明:
 
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:
 
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
 
class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int i = 0;
        int j = numbers.length - 1;
        int[] result = new int[2];
        while (i < j) {
            if (i < j && numbers[i] + numbers[j] > target) {
                j--;
            } else if (i < j && numbers[i] + numbers[j] < target) {
                i++;
            } else {
                result[0] = i+1;
                result[1] = j+1;
                return result;
            }
        }
        return null;
    }
}

 

编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
 
示例 1:
 
输入: "hello"
输出: "holle"
示例 2:
 
输入: "leetcode"
输出: "leotcede"
 
 
import java.util.HashSet;
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
    public String reverseVowels(String s) {
        if(s == "" || s==null)
            return s;
        int i = 0;
        int j = s.length() - 1;
        HashSet<Character> set = new HashSet<>();
        set.add('a');
        set.add('e');
        set.add('i');
        set.add('o');
        set.add('u');
        set.add('A');
        set.add('E');
        set.add('I');
        set.add('O');
        set.add('U');
        char[] chs = s.toCharArray();
        while (i < j) {
            while (i < j && !set.contains(chs[i])) {
                i++;
            }
            while (i < j && !set.contains(chs[j])) {
                j--;
            }
            if (i < j) {
                char temp;
                temp = chs[i];
                chs[i] = chs[j];
                chs[j] = temp;
                i++;
                j--;
            }
        }
        return new String(chs);
    }
}
  • 验证回文字符串 Ⅱ
 
给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
示例 1:
输入: "aba"
输出: True
示例 2:
输入: "abca"
输出: True
解释: 你可以删除c字符。
注意:
1. 字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。
class Solution {
    public boolean validPalindrome(String s) {
        for (int i = 0, j = s.length() - 1; i < j; i++, j--) {
            if (s.charAt(i) != s.charAt(j)) {
                return check(s, i + 1, j) || check(s, i, j - 1);
            }
        }
        return true;
    }
    public boolean check(String s, int i, int j) {
        while (i < j) {
            if (s.charAt(i++) != s.charAt(j--)) {
                return false;
            }
        }
        return true;
    }
}
  • 两数平方和
class Solution {
    public boolean judgeSquareSum(int c) {
        int i = 0;
        int j = (int) Math.sqrt(c);
        while (i <= j) {
            int sum = i * i + j * j;
            if (sum == c)
                return true;
            if (sum > c)
                j--;
            else
                i++;
        }
        return false;
    }
}

 

  • 合并有序数组

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

说明:

初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。

你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。

示例:

输入:

nums1 = [1,2,3,0,0,0], m = 3

nums2 = [2,5,6],       n = 3

输出: [1,2,2,3,5,6]

class Solution {

    public void merge(int[] nums1, int m, int[] nums2, int n) {

        int i = m - 1;

        int j = n - 1;

        int k = m + n - 1;

        while (i >= 0 && j >= 0) {

            if (nums1[i] > nums2[j]) {

                nums1[k--] = nums1[i--];

            } else {

                nums1[k--] = nums2[j--];

            }

        }

        while (j >= 0) {

            nums1[k--] = nums2[j--];

        }

    }

}

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]

输出: [1,3,12,0,0]

说明:

必须在原数组上操作,不能拷贝额外的数组。

尽量减少操作次数。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/move-zeroes

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 

//leetcode submit region begin(Prohibit modification and deletion)

class Solution {

    public void moveZeroes(int[] nums) {

        int i = 0;

        for (int j = 1; j < nums.length; j++) {

            if (nums[i] == 0 && nums[j] != 0) {

                nums[i] = nums[j];

                nums[j] = 0;

            }

            if (nums[i] != 0) {

                i++;

            }

        }

    }

}

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成

示例 1:

给定数组 nums = [1,1,2],

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝

int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。

// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。

for (int i = 0; i < len; i++) {

    print(nums[i]);

}

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

//leetcode submit region begin(Prohibit modification and deletion)

class Solution {

public int removeDuplicates(int[] nums) {

if(nums.length==0){

return 0;

}

int i = 0;

for(int j = 1;j < nums.length;j++){

if(nums[i]!=nums[j]){

nums[++i] = nums[j];

}

}

return i+1;

}

}

//leetcode submit region end(Prohibit modification and deletion)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1

给定 nums = [3,2,2,3], val = 3,

函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,1,2,2,3,0,4,2], val = 2,

函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

注意这五个元素可为任意顺序。

你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝

int len = removeElement(nums, val);

// 在函数里修改输入数组对于调用者是可见的。

// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。

for (int i = 0; i < len; i++) {

    print(nums[i]);

}

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/remove-element

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 

//leetcode submit region begin(Prohibit modification and deletion)

class Solution {

public int removeElement(int[] nums, int val) {

if (nums == null || nums.length == 0)

return 0;

int j = 0;

for (int i = 0; i < nums.length; i++) {

if (nums[i] != val) {

nums[j] = nums[i];

j++;

}

}

return j;

}

}

//leetcode submit region end(Prohibit modification and deletion)

11 盛最多水的容器

给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

 

 

图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例:

输入:[1,8,6,2,5,4,8,3,7]

输出:49

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/container-with-most-water

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

//leetcode submit region begin(Prohibit modification and deletion)

class Solution {

public int maxArea(int[] height) {

    int i = 0;

    int j = height.length - 1;

    int max = Math.min(height[i], height[j]) * (j - i);

    while (i < j) {

        if (Math.min(height[i], height[j]) * (j - i) > max) {

            max = Math.min(height[i], height[j]) * (j - i);

        }

    if (height[i] < height[j]) {

        i++;

    } else {

        j--;

    }

  }

    return max;

  }

}

//leetcode submit region end(Prohibit modification and deletion)

524. 通过删除字母匹配到字典里最长单词

给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到。如果答案不止一个,返回长度最长且字典顺序最小的字符串。如果答案不存在,则返回空字符串。
 
示例 1:
 
输入:
s = "abpcplea", d = ["ale","apple","monkey","plea"]
 
输出:
"apple"
示例 2:
 
输入:
s = "abpcplea", d = ["a","b","c"]
 
输出:
"a"
说明:
 
所有输入的字符串只包含小写字母。
字典的大小不会超过 1000。
所有输入的字符串长度不会超过 1000。
 
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 

 

class Solution {
    public static String findLongestWord(String s, List<String> d) {
        Set<String> listSet = new TreeSet<>(d);
        ArrayList<String> list = new ArrayList<>();
        for (String s2 : listSet) {
            char[] ch1 = s.toCharArray();
            char[] ch2 = s2.toCharArray();
            int i = 0;
            int j = 0;
            while (i < s.length() && j < s2.length()) {
                while (i < s.length() && j < s2.length() && ch1[i] != ch2[j]) {
                    i++;
                }
                while (i < s.length() && j < s2.length() && ch1[i] == ch2[j]) {
                    i++;
                    j++;
                }
                if (j == s2.length()) {
                    list.add(s2);
                }
            }
        }
        if (list.size() == 0) {
            return "";
        } else {
            String result = list.get(0);
            for (String string : list) {
                if (string.length() > result.length()) {
                    result = string;
                }
            }
            return result;
        }
    }
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值