快慢指针技巧

删除排序数组中的重复项

参考: https://leetcode.cn/problems/remove-duplicates-from-sorted-array/

数组算法题解决技巧_数组

private int removeDuplicates(int[] nums){
        if(nums.length == 0) return 0;
        int slow = 0,fast = 0;
        while (fast < nums.length){
            if(nums[slow] != nums[fast]){
                nums[slow] = nums[fast];
                slow++;
            }
            fast++;
        }
        return slow+1;
    }

扩展:删除链表中的重复元素

参考: https://leetcode.cn/problems/remove-duplicates-from-sorted-list/

ListNode deleteDuplicates(ListNode head) {
    if (head == null) return null;
    ListNode slow = head, fast = head;
    while (fast != null) {
        if (fast.val != slow.val) {
            // nums[slow] = nums[fast];
            slow.next = fast;
            // slow++;
            slow = slow.next;
        }
        // fast++
        fast = fast.next;
    }
    // 断开与后面重复元素的连接
    slow.next = null;
    return head;
}

移除元素(数组中的元素原地删除)

参考https://leetcode.cn/problems/remove-element/

数组算法题解决技巧_数组_02

/**
     * 移除元素(原地删除元素)
     * @param nums
     * @param val
     * @return
     */
    static int removeElement(int[] nums, int val){
        if(nums.length == 0) return 0;
        int slow = 0,fast = 0;
        while (fast < nums.length){
            if(nums[fast] != val){
                nums[slow] = nums[fast];
                slow++;
            }
            fast++;
        }
        return slow;
    }

移动零(原地修改元素)

**参考:**https://leetcode.cn/problems/move-zeroes/

/**
     * 移除元素(原地删除元素)
     * @param nums
     * @param val
     * @return
     */
    static int removeElement(int[] nums, int val){
        if(nums.length == 0) return 0;
        int slow = 0,fast = 0;
        while (fast < nums.length){
            if(nums[fast] != val){
                nums[slow] = nums[fast];
                slow++;
            }
            fast++;
        }
        return slow;
    }
    /**
     * 移动0(原地修改元素)
     */
    void moveZeroes(int[] nums){
        int target = removeElement(nums, 0);
        for (int i = target; i < nums.length; i++) {
            nums[i] = 0;
        }
    }

左右指针技巧

二分查找

int binarySearch(int[] nums, int target) {
    // 一左一右两个指针相向而行
    int left = 0, right = nums.length - 1;
    while(left <= right) {
        int mid = (right + left) / 2;
        if(nums[mid] == target)
            return mid; 
        else if (nums[mid] < target)
            left = mid + 1; 
        else if (nums[mid] > target)
            right = mid - 1;
    }
    return -1;
}

两数之和

数组算法题解决技巧_两个指针_03

int[] twoSum(int[] nums, int target) {
    // 一左一右两个指针相向而行
    int left = 0, right = nums.length - 1;
    while (left < right) {
        int sum = nums[left] + nums[right];
        if (sum == target) {
            // 题目要求的索引是从 1 开始的
            return new int[]{left + 1, right + 1};
        } else if (sum < target) {
            left++; // 让 sum 大一点
        } else if (sum > target) {
            right--; // 让 sum 小一点
        }
    }
    return new int[]{-1, -1};
}

反转数组(反转字符串)

**参考:**https://leetcode.cn/problems/reverse-string/

/**
     * 字符串反转
     * @param s
     */
    void reverseString(char[] s) {
        int left = 0,right = s.length-1;
        while (left < right){
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }

回文数判断(最长回文数)

boolean isPalindrome(String s) {
    // 一左一右两个指针相向而行
    int left = 0, right = s.length() - 1;
    while (left < right) {
        if (s.charAt(left) != s.charAt(right)) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

最长回文数

参考https://leetcode.cn/problems/longest-palindromic-substring/

找回文串的难点在于,回文串的的长度可能是奇数也可能是偶数,解决该问题的核心是从中心向两端扩散的双指针技巧

如果回文串的长度为奇数,则它有一个中心字符;如果回文串的长度为偶数,则可以认为它有两个中心字符。所以我们可以先实现这样一个函数:

数组算法题解决技巧_两个指针_04

static String palindrome(String s,int l,int r){
        while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)){
            //双指针两边展开
            l--;
            r++;
        }
        return s.substring(l+1,r);
    }
    static String longestPalindrome(String s) {
        String res = "";
        for (int i = 0; i < s.length(); i++) {
            // 以 s[i] 为中心的最长回文子串
            String s1 = palindrome(s, i, i);
            // 以 s[i] 和 s[i+1] 为中心的最长回文子串
            String s2 = palindrome(s, i, i + 1);
            // res = longest(res, s1, s2)
            res = res.length() > s1.length() ? res : s1;
            res = res.length() > s2.length() ? res : s2;
        }
        return res;
    }
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6