Loading

ARTS_0

概述

ARTS 是耗子叔发起的编程挑战:

每周完成一个ARTS: 每周至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tip、Share 简称ARTS)

Algorithm

220. 存在重复元素 III

Description: 给你一个整数数组 nums 和两个整数 kt 。请你判断是否存在 两个不同下标 ij,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k

如果存在则返回 true,不存在返回 false

示例 1:

输入:nums = [1,2,3,1], k = 3, t = 0
输出:true

示例 2:

输入:nums = [1,0,1,1], k = 1, t = 2
输出:true

示例 3:

输入:nums = [1,5,9,1,5,9], k = 2, t = 3
输出:false

提示:

  • 0 <= nums.length <= 2 * 104
  • -231 <= nums[i] <= 231 - 1
  • 0 <= k <= 104
  • 0 <= t <= 231 - 1

思路:

看到abs(a - b) <= c就应该有进行滑窗的警觉了。

我们分析题目,abs(nums[i] - nums[j]) <= t ,同时又要 abs(i - j) <= k

那我们仔细考虑一下,abs代表的是差值,也可以说是一个区间。那么我们滑过去的同时,是否已经包括了所需要的区间了呢?

如下图:

假设当前在i,那么我们需要检查下标范围为i-k~i+k内的所有数,这个复杂度最坏是会达到O(n^2)的。

那我们假设只检查i~i+k的区间呢,那当我们检查i-k的位置是,检查的是i-k~i, 到i位置时检查的是i~i+k。这样的话要检查的区间就少了一半了。

但是,问题仍然没有解决,虽然数量少了一半,但还是不能摆脱O(n^2)的复杂度。于是考虑上一个数据结构,能配合滑窗,进行删除与添加,并能支持lower_bound,与upper_bound的查询,同时又要有重复元素——multiset

所幸的是这题不是问我们有多少组满足的,而是问是否存在,那么我们其实就只需要

// 查看是否有比a[i]-t大,比a[i]+t小的元素就行
it = multiset.lower_bound(a[i] - t)
if (it != multiset.end() && *it <= a[i] - t)

Solution:

class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int indexDiff, int valueDiff) {
        multiset<int> ms;
        for (int i = 0; i < nums.size(); ++ i) {
            if (i > indexDiff) ms.erase(ms.find(nums[i-indexDiff-1]));
            multiset<int>::iterator it = ms.lower_bound(nums[i]-valueDiff);
            if (it != ms.end() && *it <= nums[i] + valueDiff) {
                return true;
            }
            ms.insert(nums[i]);
        }
        return false;
    }
};

ps. 居然只击败了5%...看了下题解,说可以用桶排序。

这个还挺妙的,也就是说,按照valueDiff分桶,那么我们就只需要查看当前元素所在的桶有没有其他元素,之后前后两个桶内的元素差值有没有大于valueDiff就行

一个桶只会有一个元素,如果有其它元素的话,说明已经符合题目条件,直接 return true 就行。

桶并不是一开始分好的,因为数值太大,但是我们可以轻易地得到出现元素所在桶的id,于是就可以动态开一个map,来记录元素出现的桶的id的出现次数。

妙啊~,就不写了。

Review

这篇文章主要是讲一种Clean-Architecture in Golang。作者似乎是受Uncle Bob启发,结合golang来讲Clean-Architecture

首先是介绍了Clean-Architecture的五个基本要求:

  1. Independent of Frameworks.
  2. Testable.
  3. Independent of UI.
  4. Independent of Database.
  5. Independent of any external agency.

然后介绍了自己的Clean-Architecture :

  • Models: This layer will store any Object’s Struct and its method.
  • Repository: The repository will store any Database handler.
  • Usecase: This layer will act as the business process handler.
  • Delivery: This layer will act as the presenter.

之后讲了一下这几层要怎么测试。

之后给了个总结:

My Comment:

这对于初入工程的我算是比较有启发,因为之前我的项目结构都是耦合在一起的,稍微加一个功能就要改很多地方。也许我也应该去读一下Uncle Bob的文章。

Tip

因为工作技术栈主要是golang,这里就大多分享一些golang技巧。

如何模拟一些其它语言中支持的for i in 0..N循环代码块?

我们可以通过遍历一个元素尺寸为零的数组或者一个空数组指针来模拟这样的循环。 例如:

package main

import "fmt"

func main() {
	const N = 5

	for i := range [N]struct{}{} {
		fmt.Println(i)
	}
	for i := range [N][0]int{} {
		fmt.Println(i)
	}
	for i := range (*[N]int)(nil) {
		fmt.Println(i)
	}
}

Share

看hackernoon看到一篇讲元宇宙(metaverse)的,想到前阵子这个概念挺火,但貌似我还不知道这个是什么东西。于是就去知乎和谷歌搜索了一下“元宇宙”。

原来,元宇宙就是一个虚拟的世界,这个世界跟虚拟人生差不多,有society,economy,culture等。

现在真的能有元宇宙吗?我觉得不大可能,于是到知乎搜了一下元宇宙。

这篇文章以及这篇文章下面的评论区,我觉得说的很好。

https://zhuanlan.zhihu.com/p/396134310

一些让我共鸣的评论:

1 :

2 :

3:

4:

5:

posted @ 2022-09-14 10:07  ViKyanite  阅读(43)  评论(1编辑  收藏  举报