leetcode(Hot100)——数组篇

1、两数之和

leetcode(Hot100)——数组篇_第1张图片

        本题使用哈希法,用一个哈希Map保存数组的值以及对应下标,代码如下:

class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap map = new HashMap<>();
        for(int i=0; i

2、字母异位词分组

leetcode(Hot100)——数组篇_第2张图片

        本题使用哈希法,使用哈希表存储每一组字母异位词,键为这组异位词的标志(将字符串排序后的字符串作为键),值为这组字母异位词形成的列表。

        代码如下:

class Solution {
    public List> groupAnagrams(String[] strs) {
        Map> map = new HashMap<>();
        for(String str : strs){
            char[] array = str.toCharArray();//将字符串转化成字符数组,方便排序
            Arrays.sort(array);
            String key = new String(array);//将排序后的字符数组转回字符串,当作哈希表的键
            List list = map.getOrDefault(key,new ArrayList());//从哈希表取出当前键对应的值,若无则默认返回一个数组列表
            list.add(str);//将当前字符串加入数组列表
            map.put(key,list);
        }
        return new ArrayList<>(map.values());
    }
}

3、最长连续序列

leetcode(Hot100)——数组篇_第3张图片

         考虑到数组中可能有重复元素需要去重,并且有查找操作,可以使用HashSet集合,既可以去除重复元素,又方便进行查找操作。

        遍历集合,如果有当前元素的后继元素,则序列长度++。 代码如下:

class Solution {
    public int longestConsecutive(int[] nums) {
        Set hashSet = new HashSet<>();
        int ans = 0;
        for(int num : nums){
            hashSet.add(num);
        }
        for(int num : hashSet){
            //有前驱元素直接跳过,因为此时肯定不是最长序列。
            if(!hashSet.contains(num-1)){
                int local_max = 1;
                while(hashSet.contains(num+1)){
                    local_max += 1;
                    num += 1;
                }
                ans = Math.max(ans , local_max); 
            }
        }
        return ans;
    }
}

4、移动零

leetcode(Hot100)——数组篇_第4张图片

        本题需要原地操作,使用双指针解决,快指针用于遍历旧数组,慢指针用于维护新数组。代码如下:

class Solution {
    public void moveZeroes(int[] nums) {
        int fast = 0;
        int slow = 0;
        while(fast < nums.length){
            if(nums[fast] == 0){
                fast++;
            }
            else{
                nums[slow] = nums[fast];
                slow++;
                fast++;
            }
        }
        for(int i=slow; i

 5、盛最多水的容器

leetcode(Hot100)——数组篇_第5张图片

        本题利用双指针分别指向数组头和尾,然后用一个变量保存最大面积,每记录一次,让指针移动一格,这里比较关键的点就是要让height值比较低的那个指针移动,最后当两个指针相碰时,结束循环 。

        代码如下:

class Solution {
    public int maxArea(int[] height) {
        int left = 0;
        int right = height.length-1;
        int ans = 0;
        while(left < right){
            ans = Math.max(ans , (right-left)*Math.min(height[left],height[right]));
            if(height[left] < height[right]){
                left++;
            }
            else{
                right--;
            }
        }
        return ans;
    }
}

6、三数之和

leetcode(Hot100)——数组篇_第6张图片

        本题采用排序+双指针的解法,关键点是需要去重,代码如下:

class Solution {
    public List> threeSum(int[] nums) {
        List> ans = new ArrayList<>();
        Arrays.sort(nums);
        for(int i=0; i0 && nums[i]==nums[i-1]) continue;
            int left = i+1;
            int right = nums.length-1;
            while(left < right){
                if(left>i+1 && nums[left]==nums[left-1]){
                    left++;
                    continue;
                }
                if(right 0) right--;
                else{
                    List list = new ArrayList<>();
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    ans.add(list);
                    left++;
                    right--;
                }
            }    
        }
        return ans;
    }
}

7、接雨水

leetcode(Hot100)——数组篇_第7张图片

        经典题目接雨水,思路就是用两个数组 left 和 right 分别保存当前柱子左侧和右侧的最高柱子(第一个和最后一个柱子不需要保存), 再分别求出每一列柱子能存储的水量。 代码如下:

class Solution {
    public int trap(int[] height) {
        int left[] = new int[height.length];
        int right[] = new int[height.length];
        int left_max = height[0];
        int right_max = height[height.length-1];
        int ans = 0;
        //当前柱子左侧的最高柱子
        for(int i=1; i=1; i--){
            right[i] = right_max;
            right_max = Math.max(right_max,height[i]);
        }
        for(int i=1; i

8、和为 K 的子数组

leetcode(Hot100)——数组篇_第8张图片

        暴力双层for循环:

class Solution {
    public int subarraySum(int[] nums, int k) {
        int ans = 0;
        for(int i=0; i

9、合并区间

leetcode(Hot100)——数组篇_第9张图片

        本题需要先对数组进行排序,以数组的第一个元素进行从小到大的排序。然后遍历各子数组看是否有重叠部分,有的话则合并。 代码如下:

class Solution {
    public int[][] merge(int[][] intervals) {
        List ans = new ArrayList<>();
        Arrays.sort(intervals,new Comparator(){
            public int compare(int[] a, int[] b){
                return a[0] - b[0];
            }
        });
        ans.add(intervals[0]);
        for(int i=1; i= intervals[i][0]){
                ans.get(ans.size()-1)[1] = Math.max(ans.get(ans.size()-1)[1] , intervals[i][1]);
            }
            else{
                ans.add(intervals[i]);
            }
        }
        return ans.toArray(new int[ans.size()][]);
    }
}

10、轮转数组

leetcode(Hot100)——数组篇_第10张图片

       思路是new一个新数组,将轮转之后的元素加入新数组中,然后再将新数组赋值给旧数组。

        这里赋值需要注意不能直接使用等于号,这里我使用System.arraycopy()方法,其中有五个参数,分别为:源数组、赋值的起始位置、目的数组、赋值的起始位置、需要赋值的长度。 代码如下:

class Solution {
    public void rotate(int[] nums, int k) {
        int[] ans = new int[nums.length];
        if(k % nums.length == 0) return;
        if(k > nums.length){
            k = k % nums.length;
        }
        int t = k;
        for(int i=nums.length-1; i>=nums.length-k; i--){
            ans[t-1] = nums[i];
            t--;
        }
        int j = k;
        for(int i=0; i

11、除自身以外数组的乘积 

leetcode(Hot100)——数组篇_第11张图片

        定义两个数组left和right,left[i]和right[i]分别记录当前元素 i 左边和右边的乘积。 特别的,left第一个元素需初始化为1,right最后一个元素也需初始化为1。 代码如下:

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int[] ans = new int[nums.length];
        int[] left = new int[nums.length];
        int[] right = new int[nums.length];
        left[0] = 1;
        right[nums.length-1] = 1;
        for(int i=1; i=0; i--){
            right[i] = right[i+1] * nums[i+1];
        }
        for(int i=0; i

 

你可能感兴趣的:(leetcode(Hot100)——数组篇)