万字拿下leetcode线性数据结构

Posted 深林无鹿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了万字拿下leetcode线性数据结构相关的知识,希望对你有一定的参考价值。

文章有点长,推荐收藏

leetcode 刷题的正确打开方式

一、 线性数据结构刷题思路

数组-> 链表-> 哈希表->字符串->栈与队列

二、 数组系列

1、二分查找

从最简单的二分开始

  • leetcode 704. 二分查找
    在这里插入图片描述
    code :
class Solution {
    public int search(int[] nums, int target) {
        int pivot, left = 0, right = nums.length - 1;
        while (left <= right) {
            pivot = left + right >> 1;
            if (nums[pivot] == target) {
                return pivot; 
            } else if (nums[pivot] < target) {
                left = pivot + 1;
            } else {
                right = pivot - 1;
            }
        }
        return -1;
    }
}
  • leetcode 35.搜索插入位置
    在这里插入图片描述
    code:
class Solution {
    public int searchInsert(int[] nums, int target) {
        int pivot, left = 0, right = nums.length - 1;
        while (left <= right) {
            pivot = left + right >> 1;
            if (nums[pivot] == target) {
                return pivot;
            } else if (nums[pivot] < target) {
                left = pivot + 1;
            } else {
                right = pivot - 1;
            }
        }
        return right + 1;
    }
}
  • leetcode 34. 在排序数组中查找元素的第一个和最后一个位置
    在这里插入图片描述
    code:
class Solution {
	// 根据二分,找到的元素向左向右遍历
    public int[] searchRange(int[] nums, int target) {
        int pos = binarySearch(nums, target);
        if (pos == -1) return new int[]{-1, -1};
        int i, j, temp = pos;
        while (nums[temp] == target) {
            temp --;
            if (temp < 0) break;
        }
        i = temp + 1;
        while (nums[pos] == target) {
            pos ++;
            if (pos > nums.length - 1) break;
        }
        j = pos - 1;
        return new int[]{i, j};
    }
	// 经典的二分查找
    public int binarySearch(int[] nums, int target) {
        int pivot, left = 0, right = nums.length - 1;
        while (left <= right) {
            pivot = left + right >> 1;
            if (nums[pivot] == target) {
                return pivot;
            } else if (nums[pivot] < target) {
                left = pivot + 1;
            } else {
                right = pivot - 1;
            }
        }
        return -1;
    }
}
  • leetcode 69. x 的平方根
    在这里插入图片描述
    code:
class Solution {
    public int mySqrt(int x) {
        int pivot, left = 0, right = x, ans = -1;
        while (left <= right) {
            pivot = left + right >> 1;
            if ((long) pivot * pivot <= x) {
                ans = pivot;
                left = pivot + 1;
            } else {
                right = pivot - 1;
            }
        }
        return ans;
    }
}
  • leetcode 367. 有效的完全平方数
    在这里插入图片描述
    code:
class Solution {
    public boolean isPerfectSquare(int num) {
        long i = binarySearch(num);
        if ((long)i*i == num) return true;
        return false;
    }
    public long binarySearch(int x) {
        long pivot, left = 0, right = x, ans = -1;
        while (left <= right) {
            pivot = left + right >> 1;
            long mul = (long)(pivot * pivot);
            if (mul <= x) {
                ans = pivot;
                left = pivot + 1;
            } else {
                right = pivot - 1;
            }
        } 
        return ans;
    }
}

2、移除数组元素(双指针等等)

核心思路:双指针

  • leetcode 27. 移除元素
    在这里插入图片描述

双指针:

class Solution {
    public int removeElement(int[] nums, int val) {
        int n = nums.length;
        int left = 0;
        for (int right = 0; right < n; right++) {
            if (nums[right] != val) {
                nums[left] = nums[right];
                left++;
            }
        }
        return left;
    }
}
  • leetcode 26. 删除有序数组中的重复项
    在这里插入图片描述

双指针

class Solution {
    public int removeDuplicates(int[] nums) {
        int len = nums.length;
        int left = 0;
        for (int right = 1; right < len; right ++) {
            if (nums[right] != nums[left]) {
                nums[++ left] = nums[right];
            }
        }
        // nums = Arrays.copyOfRange(nums, 0, left);
        return left + 1;
    }
}
  • leetcode 283. 移动零
    在这里插入图片描述

双指针

class Solution {
    public void moveZeroes(int[] nums) {
        int left = 0;
        for (int right = 0; right < nums.length; right ++) {
            if (nums[right] != 0) {
                int temp = nums[right];
                nums[right] = nums[left];
                nums[left] = temp;
                left ++;
            }
        }
    }
}
  • leetcode 844. 比较退格的字符串
    在这里插入图片描述

重构字符串

class Solution {
    public boolean backspaceCompare(String S, String T) {
        return build(S).equals(build(T));
    }

    public String build(String str) {
        StringBuffer ret = new StringBuffer();
        int length = str.length();
        for (int i = 0; i < length; ++i) {
            char ch = str.charAt(i);
            if (ch != '#') {
                ret.append(ch);
            } else {
                if (ret.length() > 0) {
                    ret.deleteCharAt(ret.length() - 1);
                }
            }
        }
        return ret.toString();
    }
}

双指针

class Solution {
    public boolean backspaceCompare(String S, String T) {
        int i = S.length() - 1, j = T.length() - 1;
        int skipS = 0, skipT = 0;

        while (i >= 0 || j >= 0) {
            while (i >= 0) {
                if (S.charAt(i) == '#') {
                    skipS++;
                    i--;
                } else if (skipS > 0) {
                    skipS--;
                    i--;
                } else {
                    break;
                }
            }
            while (j >= 0) {
                if (T.charAt(j) == '#') {
                    skipT++;
                    j--;
                } else if (skipT > 0) {
                    skipT--;
                    j--;
                } else {
                    break;
                }
            }
            if (i >= 0 && j >= 0) {
                if (S.charAt(i) != T.charAt(j)) {
                    return false;
                }
            } else {
                if (i >= 0 || j >= 0) {
                    return false;
                }
            }
            i--;
            j--;
        }
        return true;
    }
}
  • leetcode 977. 有序数组的平方
    在这里插入图片描述

双指针 (左右边界指针扫描,归并逆序存进新数组)

class Solution {
    public int[] sortedSquares(int[] nums) {
        int n = nums.length;
        int[] res = new int[n];
        for (int left = 0, right = n - 1, pos = n - 1; left <= right ;) {
            int l = nums[left] * nums[left];
            int r = nums[right] * nums[right];
            if (l <= r) {
                res[pos --] = r;
                right --;
            } else {
                res[pos --] = l;
                left ++;
            }
        }
        return res;
    }
}

3、滑动窗口系列(滑动窗口+固定窗口)

滑动窗口系列:

  • leetcode 209.长度最小的子数组
    在这里插入图片描述
    滑动窗口
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int n = nums.length;
        int left = 0, sum = 0, ans = Integer.MAX_VALUE;
        for (int right = 0; right < n; right ++) {
            sum += nums[right];
            while (sum >= target) {
                ans = Math.min(ans, right - left + 1);
                sum -= nums[left];
                left ++;
            }
        }
        return ans == Integer.MAX_VALUE ? 0 : ans;
    }
}
  • leetcode 904. 水果成篮
    在这里插入图片描述
    在这里插入图片描述
    普通的滑动窗口:
class Solution {
    public int totalFruit(int[] tree) {
        int n = tree.length;
        if (n == 0) return 0;
        if (n == 1) return 1;
        int left = 0, ans = 0, sum = 0;

        HashMap<Integer, Integer> basket = new HashMap<>();
        for (int right = 0; right < n; right ++) {
            basket.put(tree[right], basket.getOrDefault(tree[right], 0) + 1);
            sum = 0;
            while (basket.size() > 2) {
                basket.put(tree[left], basket.get(tree[left]) - 1);
                if (basket.get(tree[left]) == 0) basket.remove(tree[left]);
                left ++;
            }
            ans = Math.max(ans, right - left + 1);
        }
        return ans;
    }
}

史上最快滑动窗口:

class Solution {
    public int totalFruit(int[] tree) {
        int maxLen = 0, len = tree.length;
        int start = 0, end = 0;
        int one = tree[end], two = 0;
        // 找第一种果树
        while(end < len && tree[end] == one) end以上是关于万字拿下leetcode线性数据结构的主要内容,如果未能解决你的问题,请参考以下文章

万字拿下leetcode线性数据结构

万字梳理,带你拿下Java 面试题!

万字梳理,带你拿下 Java 面试题!

扔掉你的算法书!1小时零基础拿下贪心算法!(17道题+万字儿童级解析+数十张图解)

扔掉你的算法书!1小时零基础拿下贪心算法!(17道题+万字儿童级解析+数十张图解)

扔掉你的算法书!1小时零基础拿下贪心算法!(17道题+万字儿童级解析+数十张图解)