【leetcode-双指针】移动零/颜色分类/合并两个有序数组/反转字符串/反转字符串中的元音字母/反转字符串中的单词

文章目录

    • 移动零
      • 双指针
    • 颜色分类
      • 双指针
    • 合并两个有序数组
      • 双指针法从后往前
    • 反转字符串
      • 双指针
    • 反转字符串中的元音字母
      • 双指针
    • 反转字符串中的单词
      • 双指针

移动零

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

示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

双指针

class Solution {
    public void moveZeroes(int[] nums) {
        int len = nums.length;
        for (int left = 0, right = 0; right < len; right++) {
            if (nums[right] != 0) {
                nums[left] = nums[right];
                if (left++ != right)
                    nums[right] = 0;
            }
        }
    }
}

颜色分类

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

示例 1:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]

示例 2:
输入:nums = [2,0,1]
输出:[0,1,2]

示例 3:
输入:nums = [0]
输出:[0]

示例 4:
输入:nums = [1]
输出:[1]

双指针

class Solution {
    public void sortColors(int[] nums) {
        int n = nums.length;
        int p0 = 0, p1 = 0;
        for (int i = 0; i < n; i++) {
            if (nums[i] == 0) {
                swap(nums, i, p0);
                if (p0 < p1)
                    swap(nums, i, p1); 
                p0++;
                p1++;
            } else if (nums[i] == 1)
                swap(nums, i, p1++); 
        }
    }

    private void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}
class Solution {
    public void sortColors(int[] nums) {
        int n = nums.length;
        int p0 = 0, p2 = n - 1;
        for (int i = 0; i <= p2; i++) {
            while (i <= p2 && nums[p2] == 2)
                p2--;
            if (i > p2)
                break;
            if (nums[i] == 2)
                swap(nums, i, p2--); 
            if (nums[i] == 0)
                swap(nums, i, p0++); 
        }
    }

    private void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

合并两个有序数组

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。

示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]

示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]

双指针法从后往前

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        if (n == 0)
            return;
        if (m == 0) {
            System.arraycopy(nums2, 0, nums1, 0, n);
            return;
        }  

        int i = m - 1, j = n - 1, cur = m + n - 1;
        while (cur >= 0) {
            if (nums1[i] > nums2[j]) {
                nums1[cur--] = nums1[i--];
            } else {
                nums1[cur--] = nums2[j--];
            }
            if (i < 0) {
                System.arraycopy(nums2, 0, nums1, 0, j + 1);
                break;
            }
            if (j < 0)
                break;
        }
    }
}

反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

示例 1:
输入:[“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]

示例 2:
输入:[“H”,“a”,“n”,“n”,“a”,“h”]
输出:[“h”,“a”,“n”,“n”,“a”,“H”]

双指针

class Solution {
    public void reverseString(char[] s) {
        int i = 0, j = s.length - 1;
        while (i < j) 
            swap(s, i++, j--);
    }

    private void swap(char[] s, int i, int j) {
        char c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

反转字符串中的元音字母

编写一个函数,以字符串作为输入,反转该字符串中的元音字母。

示例 1:
输入:“hello”
输出:“holle”

示例 2:
输入:“leetcode”
输出:“leotcede”

双指针

class Solution {
    public String reverseVowels(String s) {
        char[] sChar = s.toCharArray();
        int i = 0, j = sChar.length - 1;
        while (i < j) {
            while (i < j && !isVowel(sChar[i]))
                i++;
            while (i < j && !isVowel(sChar[j]))
                j--;
            swap(sChar, i++, j--);
        }
        return new String(sChar);
    }

    private boolean isVowel(char c) {
        return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' 
            || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U';
    }

    private void swap(char[] s, int i, int j) {
        char c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

反转字符串中的单词

给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

示例:
输入:“Let’s take LeetCode contest”
输出:“s’teL ekat edoCteeL tsetnoc”

提示:
在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。

双指针

class Solution {
    public String reverseWords(String s) {
        char[] sChars = s.toCharArray();
        int start = 0, len = sChars.length;
        for (int i = 0; i < len; i++) {
            if (sChars[i] != ' ') {
                start = i++;
                while (i < len && sChars[i] != ' ')
                    i++;
                reverse(sChars, start, i - 1);
            }
        }
        return new String(sChars);
    }

    private void reverse(char[] str, int start, int end) {
        while (start < end) {
            char tmp = str[start];
            str[start++] = str[end];
            str[end--] = tmp;
        }
    }
}

你可能感兴趣的:(leetcode)