万字拿下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线性数据结构的主要内容,如果未能解决你的问题,请参考以下文章
扔掉你的算法书!1小时零基础拿下贪心算法!(17道题+万字儿童级解析+数十张图解)