万字拿下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++;
if(end == 以上是关于万字拿下leetcode线性数据结构的主要内容,如果未能解决你的问题,请参考以下文章