Skip to content

Commit

Permalink
'1'
Browse files Browse the repository at this point in the history
  • Loading branch information
Ainevsia committed Jul 15, 2023
1 parent fb9fe6d commit e66a403
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
63 changes: 63 additions & 0 deletions notes/src/day2/lc209.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# 209. 长度最小的子数组

## 题目描述

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

## 解题思路

哎写出来了但是很长,用双指针维护一个区间,相当于是循环不变量,

有一个观察:就是找到一个可行解后,第二个元素开始的可行解的最后一个元素一定大于或等于当前最后一个元素

所以不断地右侧生长去找到一个可行解,然后左侧缩小去尝试更小的解

```rust
struct Solution {}

impl Solution {
pub fn min_sub_array_len(target: i32, nums: Vec<i32>) -> i32 {
let n = nums.len();
let mut a = 0;
let mut b = 0;
let mut s = 0;
let mut res = 0;
while s < target && b < n {
s += nums[b];b += 1;
}
if s < target && b == n { return 0 }
res = b;
loop {

while s >= target && a < b {
s -= nums[a];
res = res.min(b - a);
a += 1;
}
while s < target && b < n {
s += nums[b];b += 1;
}
if s >= target {
res = res.min(b - a);
}
if b == n && s < target { break }
}

res as i32
}
}
```

## 学习感想

首先要思考 如果用一个for循环,那么应该表示 滑动窗口的起始位置,还是终止位置。

如果只用一个for循环来表示 滑动窗口的起始位置,那么如何遍历剩下的终止位置?

此时难免再次陷入 暴力解法的怪圈。

所以 只用一个for循环,那么这个循环的索引,一定是表示 滑动窗口的终止位置。

原来是滑动窗口,只用一个变量来表示结束的位置
5 changes: 5 additions & 0 deletions notes/src/day2/lc59.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 59. 螺旋矩阵II

## 题目描述
## 解题思路
## 学习感想
93 changes: 93 additions & 0 deletions notes/src/day2/lc977.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# 977. 有序数组的平方

## 题目描述

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。


## 解题思路

有个很直接的方法是,先取绝对值,然后sort,然后平方

但是这个是nlogn的算法,想要一个n的算法,那很显然需要用到数组有序这个特性。

其实平方是无关紧要的操作。

找到最小的元素,然后向两边双边移动?

```rust
#struct Solution {}

impl Solution {
pub fn sorted_squares(mut nums: Vec<i32>) -> Vec<i32> {
nums.iter_mut()
.filter(|&&mut x| x < 0)
.for_each(|x| *x = -*x);
let low = nums.iter().enumerate()
.fold((0, nums[0]), |(idx, v), (jdx, &x)| {
if x < v { (jdx, x) } else { ( idx, v ) }
}).0;
if low == 0 { return nums.iter().map(|x| x**x).collect() }
let mut left = low as isize - 1;
let mut right = low + 1;
let n = nums.len();
let mut v = Vec::with_capacity(n);
v.push(nums[low]);
// left -> 还需要处理的左侧第一个元素
// right 还需要处理的右侧第一个元素
while left >= 0 && right < n {
// 判断两侧
if nums[left as usize] < nums[right] {
v.push(nums[left as usize]);
left -= 1;
} else {
v.push(nums[right]);
right += 1;
}
}
if left < 0 {
while right < n {
v.push(nums[right]);
right += 1;
}
} else {
while left >= 0 {
v.push(nums[left as usize]);
left -= 1;
}
}
v.iter().map(|x| x**x).collect()
}
}
```

写出来了,但是很长,确实定义的每一个变量的明确含义一定要在写之前就很清楚

## 学习感想

数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。

我是从最小数开始构建,确实麻烦,从最大的数开始构建就是一个简单一点的从两侧开始的双指针了。

```rust
#struct Solution {}
impl Solution {
pub fn sorted_squares(mut nums: Vec<i32>) -> Vec<i32> {
let n = nums.len();
let mut v = Vec::with_capacity(n);
let mut a = 0;
let mut b = n as isize - 1;
while a <= b {
if nums[a as usize].abs() < nums[b as usize].abs() {
v.push(nums[b as usize]);
b -= 1;
} else {
v.push(nums[a as usize]);
a += 1;
}
}
v.iter().map(|x| x**x).rev().collect()
}
}```

注意是abs比较,ab都是闭区间

0 comments on commit e66a403

Please sign in to comment.