ARTS #012

ARTS #012

Posted by Dan on October 26, 2018

ARTS是由左耳朵耗子--陈皓发起的一个活动: 每周至少做一个leetcode的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的文章。(也就是Algorithm、Review、Tip、Share简称ARTS),至少坚持一年。

ARTS 012

这是第12篇

Algorihm 算法题

leetcode算法第241题.Reorganize String: 难度:中等

442. Find All Duplicates in an Array

Difficulty: Medium

Given an array of integers, 1 ≤ a[i] ≤ n ( n = size of array), some elements appear twice and others appear once.

Find all the elements that appear twice in this array.

Could you do it without extra space and in O(n) runtime?

Example:

**Input:**
[4,3,2,7,8,2,3,1]

**Output:**
[2,3]

Solution

Language: C

/**
 * Return an array of size *returnSize.
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findDuplicates(int* nums, int numsSize, int* returnSize) {
    
}

思路就是统计数字出现的次数,我的实现如下,时间复杂度是O(n);题目的要求不需要额外的空间,这里申请的内存是用来存储结果的,空间复杂度不知道算不算违规,


int* findDuplicates(int* nums, int numsSize, int* returnSize) {
    int *charCount = (int*)malloc(sizeof(int) * (numsSize+1));
    memset(charCount, 0, sizeof(int) * (numsSize+1));
    for (int i = 0; i < numsSize; i++) {
        int data = nums[i] ;
        charCount[data]++;
    }

    * returnSize = 0;
    for (int i =0; i < numsSize +1; i++) {
        int data = charCount[i] ;
        if (data > 1) {
            charCount[(*returnSize)++] =i;
        }
    }

    return charCount;
}


在讨论区发现了一个比较巧妙的答案,如下,举个例子说明,比如如果输入的nums是[2,3,2],第一次num=abs(nums[0]); num的值是2,2-1对应的nums的值是3,然后加个负号,这时nums是[2,-3,2],当第三次num=abs(nums[2);时,num的值是2,-1对应的nums的值就是-3,说明对应的下标已经出现过,

int* findDuplicates(int* nums, int numsSize, int* returnSize) {
    if(nums==NULL||numsSize<2)
    {
        *returnSize=0;
        return NULL;
    }
    *returnSize=0;
    int *result=(int *)malloc(sizeof(int)*(numsSize/2));
    for(int i=0;i<numsSize;i++)
    {
        int num=abs(nums[i]);
        if(nums[num-1]>0)
            nums[num-1]=-nums[num-1];
        else
            result[(*returnSize)++]=num;
    }
    return result;
}

Review

这篇文章来自 https://medium.freecodecamp.org/how-to-think-like-a-programmer-lessons-in-problem-solving-d1d8bf1de7d2

这篇文章主要阐述了程序员应该怎么解决问题(This article focuses on how programmers should solve problems): 新手程序员一般处理bug的方式就是一遍的一遍的尝试,这种处理问题的方式非常低效(The way that new programmers solve bugs is to try it over and over again, which is very inefficient)。 正确的方法应该是建立自己解决问题的一般方法,包括以下步骤(The right approach should be to establish your own general approach to the problem, including the following steps): 1 首先要搞清楚问题,真正理解问题(The first thing to do is to figure out the problem and really understand it)。 2 不要着急解决问题,花点时间分析和思考问题,做出一个计划(Instead of rushing to solve a problem, take the time to analyze and think about it and make a plan)。 3 分解问题 ,把大问题分解为小问题,各个击破(Break down the problem. Break down the big problem into small problems)。 4 遇到难以解决的小问题时,首先不要急躁,静下心来,可以使用重新审视问题、搜索、debug的方式来解决(When you encounter a small problem that is difficult to solve, first don’t be impatient and settle down. You can solve it by re-examining the problem, searching, and debug)。 5 不要害怕遇到问题,只有解决的问题多了,才能提高自己的能力成为专家(Don’t be afraid to encounter problems. Only by solving more problems can you improve your ability to become an expert)

文章详细内容如下:

How to think like a programmer — lessons in problem solving

By Richard Reis

If you’re interested in programming, you may well have seen this quote before: 如果你对编程感兴趣,你可能已经见过这句引语了:

“Everyone in this country should learn to program a computer, because it teaches you to think.” — Steve Jobs

You probably also wondered what does it mean, exactly, to think like a programmer? And how do you do it?? 您可能还想知道,像程序员一样思考到底意味着什么?你是怎么做到的?

Essentially, it’s all about a more effective way for problem solving. 从本质上讲,这是一种更有效的解决问题的方法。

In this post, my goal is to teach you that way. 在这篇文章中,我的目标是教你用这种方式。

By the end of it, you’ll know exactly what steps to take to be a better problem-solver. 到最后,你就会知道怎样才能更好地解决问题。

Why is this important?

Problem solving is the meta-skill. 解决问题是元技能。

We all have problems. Big and small. How we deal with them is sometimes, well…pretty random. 我们都有问题。大的和小的。我们处理这些问题的方式有时是随机的。pretty random. 随机/随意

Unless you have a system, this is probably how you “solve” problems (which is what I did when I started coding): 除非您有一个系统,否则这可能就是您“解决”问题的方式(这是我开始编写代码时所做的事情):

  1. Try a solution.
  2. If that doesn’t work, try another one.
  3. If that doesn’t work, repeat step 2 until you luck out.

Look, sometimes you luck out. But that is the worst way to solve problems! And it’s a huge, huge waste of time. 听着,有时候你运气不好。但那是解决问题最糟糕的方法!这是非常非常浪费时间的。

The best way involves a) having a framework and b) practicing it. 最好的方法是a)有一个框架,b)练习它。

“Almost all employers prioritize problem-solving skills first. 几乎所有的雇主都把解决问题的能力放在首位。

Problem-solving skills are almost unanimously the most important qualification that employers look for….more than programming languages proficiency, debugging, and system design.解决问题的技能几乎一致是雇主所寻求的最重要的资格,而不仅仅是编程语言熟练、调试和系统设计。

Demonstrating computational thinking or the ability to break down large, complex problems is just as valuable (if not more so) than the baseline technical skills required for a job.” — Hacker Rank (2018 Developer Skills Report) 演示计算思维或分解大型复杂问题的能力,与工作所需的基本技术技能一样有价值(如果不是更有价值的话)

Have a framework

To find the right framework, I followed the advice in Tim Ferriss’ book on learning,“The 4-Hour Chef”. 为了找到正确的框架,我遵循了提姆·费里斯(Tim Ferriss)关于学习的书中的建议,

It led me to interview two really impressive people: C. Jordan Ball (ranked 1st or 2nd out of 65,000+ users on Coderbyte), and V. Anton Spraul (author of the book “Think Like a Programmer: An Introduction to Creative Problem Solving”). 这让我采访了两位令人印象深刻的人

I asked them the same questions, and guess what? Their answers were pretty similar! 我问了他们同样的问题,你猜怎么着?他们的回答非常相似!

Soon, you too will know them.

Sidenote: this doesn’t mean they did everything the same way. Everyone is different. You’ll be different. But if you start with principles we all agree are good, you’ll get a lot further a lot quicker. Sidenote:这并不意味着它们每件事都以同样的方式进行。每个人都是不同的。你会是不同的。但如果你从我们都认同的好的原则开始,你会走得更远更快。

“The biggest mistake I see new programmers make is focusing on learning syntax instead of learning how to solve problems.” — V. Anton Spraul 我看到新程序员犯的最大错误是专注于学习语法,而不是学习如何解决问题

So, what should you do when you encounter a new problem? 所以,当你遇到一个新问题时,你应该怎么做?

Here are the steps:

1. Understand

Know exactly what is being asked. Most hard problems are hard because you don’t understand them (hence why this is the first step). 确切地知道被问的是什么。大多数难题之所以难,是因为你不理解它们(因此这是第一步)。

How to know when you understand a problem? When you can explain it in plain English. 如何知道什么时候你理解了一个问题?当你能用简单的英语解释它的时候。

Do you remember being stuck on a problem, you start explaining it, and you instantly see holes in the logic you didn’t see before? 你还记得被困在一个问题上,你开始解释它,然后你立刻看到逻辑上的漏洞你以前没有看到?

Most programmers know this feeling. 大多数程序员都知道这种感觉。

This is why you should write down your problem, doodle a diagram, or tell someone else about it (or thing… some people use a rubber duck). 这就是为什么你应该把你的问题写下来,画个图,或者告诉别人(或其他事情……有些人用橡皮鸭)。

“If you can’t explain something in simple terms, you don’t understand it.” — Richard Feynman

2. Plan

Don’t dive right into solving without a plan (and somehow hope you can muddle your way through). Plan your solution! 不要在没有计划的情况下一头扎进解决问题的过程中(并且希望你能混过去)。计划你的解决方案! ( Don’t dive right into (不要潜入))

Nothing can help you if you can’t write down the exact steps. 如果你不能写下确切的步骤,什么也帮不了你。

In programming, this means don’t start hacking straight away. Give your brain time to analyze the problem and process the information. 在编程中,这意味着不要立即开始进行黑客攻击。给你的大脑时间来分析问题和处理信息。

To get a good plan, answer this question: 为了得到一个好的计划,回答这个问题:

“Given input X, what are the steps necessary to return output Y?” 给定输入X,返回输出Y所需的步骤是什么?

Sidenote: Programmers have a great tool to help them with this… Comments! Sidenote:程序员有一个伟大的工具来帮助他们实现这个……注释!

3. Divide

Pay attention. This is the most important step of all.

Do not try to solve one big problem. You will cry. 不要试图解决一个大问题。你会哭的。

Instead, break it into sub-problems. These sub-problems are much easier to solve.

Then, solve each sub-problem one by one. Begin with the simplest. Simplest means you know the answer (or are closer to that answer). 然后,逐一解决每个子问题。从最简单的开始。最简单的意思是你知道答案(或者更接近那个答案)。

After that, simplest means this sub-problem being solved doesn’t depend on others being solved. 在此之后,最简单的方法意味着子问题的解决并不依赖于其他问题的解决。

Once you solved every sub-problem, connect the dots. 一旦你解决了每个子问题,把这些点连起来。

Connecting all your “sub-solutions” will give you the solution to the original problem. Congratulations! 连接所有“子解决方案”将为您提供原始问题的解决方案。恭喜你!

This technique is a cornerstone of problem-solving. Remember it (read this step again, if you must). 这种技巧是解决问题的基石。记住它(如果需要的话,再读一遍这个步骤)。

“If I could teach every beginning programmer one problem-solving skill, it would be the ‘reduce the problem technique.’ “如果我能教给每一个初学者一种解决问题的技能,那就是‘减少问题技术’。”

For example, suppose you’re a new programmer and you’re asked to write a program that reads ten numbers and figures out which number is the third highest. For a brand-new programmer, that can be a tough assignment, even though it only requires basic programming syntax. 例如,假设你是一个新程序员,你被要求编写一个程序,读取10个数字,然后算出哪个数字是第三高的。对于一个全新的程序员来说,这可能是一项艰巨的任务,尽管它只需要基本的编程语法。

If you’re stuck, you should reduce the problem to something simpler. Instead of the third-highest number, what about finding the highest overall? Still too tough? What about finding the largest of just three numbers? Or the larger of two? 如果你陷入困境,你应该把问题简化。而不是第三高的数字,如何找到最高的整体?仍然太严厉了?从三个数中找出最大的呢?还是两个中较大的那个?

Reduce the problem to the point where you know how to solve it and write the solution. Then expand the problem slightly and rewrite the solution to match, and keep going until you are back where you started.” — V. Anton Spraul 将问题简化到您知道如何解决问题并编写解决方案的程度。然后稍微展开问题,重写解决方案使其匹配,然后继续进行,直到回到起点。

4. Stuck?

By now, you’re probably sitting there thinking “Hey Richard… That’s cool and all, but what if I’m stuck and can’t even solve a sub-problem??” 现在,你可能正坐在那里想“嘿,理查德……”这很酷,但如果我卡住了,甚至不能解决子问题怎么办?

First off, take a deep breath. Second, that’s fair. 首先,深呼吸。第二,这是公平的。

Don’t worry though, friend. This happens to everyone! 别担心,朋友。每个人都会这样!

The difference is the best programmers/problem-solvers are more curious about bugs/errors than irritated. 不同之处在于,最好的程序员/问题解决者对bug /错误更好奇,而不是恼怒。

In fact, here are three things to try when facing a whammy: 事实上,当你遭遇不幸时,有三件事可以尝试:

  • Debug: Go step by step through your solution trying to find where you went wrong. Programmers call this debugging (in fact, this is all a debugger does). 调试:逐步检查您的解决方案,试图找出哪里出错了。程序员调用这个调试(实际上,这是调试器所做的全部工作)。

“The art of debugging is figuring out what you really told your program to do rather than what you thought you told it to do.”” — Andrew Singer 调试的艺术是找出你真正告诉你的程序去做什么,而不是你以为你告诉它去做什么

  • Reassess: Take a step back. Look at the problem from another perspective. Is there anything that can be abstracted to a more general approach? 重新评估:后退一步。从另一个角度来看这个问题。有什么可以抽象成更一般的方法吗?

“Sometimes we get so lost in the details of a problem that we overlook general principles that would solve the problem at a more general level. […] “有时候,我们会对问题的细节太过沉迷,以至于忽略了在更一般的层面上解决问题的一般原则。”

The classic example of this, of course, is the summation of a long list of consecutive integers, 1 + 2 + 3 + … + n, which a very young Gauss quickly recognized was simply n(n+1)/2, thus avoiding the effort of having to do the addition.” — C. Jordan Ball 当然,最经典的例子是一长串连续整数的总和,1 + 2 + 3 +…+ n,一个非常年轻的高斯很快就认识到它就是n(n+1)/2,这样就不用再做加法了。

Sidenote: Another way of reassessing is starting anew. Delete everything and begin again with fresh eyes. I’m serious. You’ll be dumbfounded at how effective this is. 旁注:另一种重新评估的方式是重新开始。删除所有内容,用全新的眼光重新开始。我是认真的。你会惊讶于这是多么有效。

  • Research: Ahh, good ol’ Google. You read that right. No matter what problem you have, someone has probably solved it. Find that person/ solution. In fact, do this even if you solved the problem! (You can learn a lot from other people’s solutions). 研究:啊,很好。你没看错。不管你有什么问题,可能有人已经解决了。找到那个人/解决方案。事实上,即使你解决了问题,也要这样做!(你可以从别人的解决方案中学到很多)。

Caveat: Don’t look for a solution to the big problem. Only look for solutions to sub-problems. Why? Because unless you struggle (even a little bit), you won’t learn anything. If you don’t learn anything, you wasted your time. 注意:不要寻找解决大问题的方法。只寻找子问题的解决方案。为什么?因为除非你努力(哪怕是一点点),否则你什么都学不到。如果你什么都没学到,你就是在浪费时间。

Practice

Don’t expect to be great after just one week. If you want to be a good problem-solver, solve a lot of problems! 不要期望仅仅一个星期就能变得很棒。如果你想成为一个好的问题解决者,解决很多问题!

Practice. Practice. Practice. It’ll only be a matter of time before you recognize that “this problem could easily be solved with .” 练习。练习。练习。迟早您会认识到“这个问题可以通过轻松地解决”。

How to practice? There are options out the wazoo! 如何练习?有很多选择!

Chess puzzles, math problems, Sudoku, Go, Monopoly, video-games, cryptokitties, bla… bla… bla…. 国际象棋游戏,数学问题,数独,垄断,视频游戏,cryptokitties,bla bla bla ….……

In fact, a common pattern amongst successful people is their habit of practicing “micro problem-solving.” For example, Peter Thiel plays chess, and Elon Musk plays video-games. 事实上,成功人士的一个普遍模式是他们练习“微观解决问题”的习惯。例如,彼得·泰尔(Peter Thiel)下棋,埃隆·马斯克(Elon Musk)玩电子游戏。

“Byron Reeves said ‘If you want to see what business leadership may look like in three to five years, look at what’s happening in online games.’ “拜伦•里夫斯(Byron Reeves)说,‘如果你想知道三到五年后商业领导力会是什么样子,那就看看网络游戏正在发生什么吧。’”

Fast-forward to today. Elon [Musk], Reid [Hoffman], Mark Zuckerberg and many others say that games have been foundational to their success in building their companies.” — Mary Meeker (2017 internet trends report) 快进到今天。埃隆·马斯克(Elon Musk)、雷德·霍夫曼(Reid Hoffman)、马克·扎克伯格(Mark Zuckerberg)和其他许多人都表示,游戏是他们成功建立公司的基石

Does this mean you should just play video-games? Not at all. 这是否意味着你应该只玩电子游戏?不客气。

But what are video-games all about? That’s right, problem-solving! 但是电子游戏到底是关于什么的呢?没错,问题解决!

So, what you should do is find an outlet to practice. Something that allows you to solve many micro-problems (ideally, something you enjoy). 所以,你应该做的是找到一个练习的出口。可以让你解决很多小问题的东西(理想情况下,你喜欢的东西)。

For example, I enjoy coding challenges. Every day, I try to solve at least one challenge (usually on Coderbyte). 例如,我喜欢编程挑战。每天,我都试图解决至少一个挑战(通常在Coderbyte)。

Like I said, all problems share similar patterns. 正如我所说,所有的问题都有相似的模式。

Conclusion

That’s all folks! 这是所有人!

Now, you know better what it means to “think like a programmer.” 现在,你知道“像程序员一样思考”是什么意思了。

You also know that problem-solving is an incredible skill to cultivate (the meta-skill). 你也知道解决问题是一种难以置信的技能(元技能)。

As if that wasn’t enough, notice how you also know what to do to practice your problem-solving skills! 如果这还不够,请注意您还知道如何练习解决问题的技巧!

Phew… Pretty cool right? 很酷吧?

Finally, I wish you encounter many problems. 最后,祝你遇到很多问题。

You read that right. At least now you know how to solve them! (also, you’ll learn that with every solution, you improve). 你没看错。至少现在你知道怎么解决了!(同时,您将了解到,每一种解决方案都会使您得到改进)。

“Just when you think you’ve successfully navigated one obstacle, another emerges. But that’s what keeps life interesting.[…] 就在你认为你已经成功地跨越了一个障碍时,另一个障碍出现了。但这正是让生活变得有趣的地方。

Life is a process of breaking through these impediments — a series of fortified lines that we must break through. 生活是一个突破这些障碍的过程——一系列我们必须突破的防线。

Each time, you’ll learn something. 每次,你都会学到一些东西。

Each time, you’ll develop strength, wisdom, and perspective. 每一次,你都将发展力量、智慧和洞察力。

Each time, a little more of the competition falls away. Until all that is left is you: the best version of you.” — Ryan Holiday (The Obstacle is the Way) 每次,更多的竞争就会消失。直到你成为最好的自己。——瑞安·霍利迪(障碍就是路)

Now, go solve some problems!

And best of luck 🙂

Special thanks to C. Jordan Ball and V. Anton Spraul. All the good advice here came from them. 这里所有的好建议都来自他们。

Also, all the programming knowledge I’ve acquired in such a short time wouldn’t have happened without Lambda School. Can’t thank/ recommend them enough.

此外,如果没有Lambda学校,我在如此短的时间内获得的所有编程知识都不会发生。非常感谢/推荐他们。

Thanks for reading! 😊 If you enjoyed it, test how many times can you hit 👏 in 5 seconds. It’s great cardio for your fingers AND will help other people see the story. 感谢你的阅读!😊如果你喜欢it,测试你能打多少次在5 seconds.👏这对你的手指是很好的有氧运动,也会帮助其他人看到这个故事。

TIPS

本周学习了使用Instrument,准备把最新的官方文档翻译一下,已经翻译了第一章的一小部分: https://dandan2009.github.io/2018/10/26/Instruments-chinese-translation/

Share

今天知道了几个新名词 “明网” 、“暗网” 、“深网” 、影子网络。明网是指我们平常使用的网络。 “暗网” 、“深网” 、“明网” 、影子网络。“暗网” 、“深网” 、影子网络都是指我们一般人接触不到的,通过常规方法访问不到的网络。这些网络大都是一些非法的信息。

一下内容均来自网络:

“暗网” DarkWeb和DeepWeb DeepWeb是广泛的无法被搜索引擎收录的互联网内容 那么什么是暗网(英语:Darknet 或 Dark Web)暗网是只能用特殊软件、特殊授权、或对电脑做特殊设置才能连上的网络。暗网的服务器地址和数据传输通常是匿名、匿踪的。与此相对,一般常用的互联网由于可追踪其真实地理位置和通信进行人的身份被称为「明网」或「表网」(英语:Clearnet)。 洋葱网络是目前公认的比较好的能够比较好的进行匿名互联网通讯方法

使用Tor 使用Tor的方式并不难。如果你能访问Google的话,只要登陆到Tor的网站http://www.theonionrouter.com/下载Tor和Tor浏览器即可~

https://www.mushroomnetworks.com/

纸牌屋 电影「罪恶城」里头的老

其实「Shadow Web(影子网络)」这个词语是今年年初才出现,而这个词语的起源是来自Reddit(类似香港高登论坛)的帖子,这也是笔者今天要和大家介绍的故事…… 一个可怕的警告。

像所有的技术都会有善恶两面一样,网络在发挥共享信息造福人类的作用时,也出现了类似社会上黑白两道的结构分层,诞生了叫做明网、深网、暗网的三兄弟。

暗网的由来

那么,这些网站是什么时候开始发展的呢?讽刺的是,与大多数技术的来源套路一样,这里就不得不提到始作俑者——美国军方。

1996年,美国海军研究试验所的科学家们提交了一篇论文,题目是《隐藏路径信息》,提出打造一个隐秘系统的构想,这个系统会让任何使用者在连接互联网时都会实时处于匿名状态,而不会向服务器泄露身份。这个系统建设十分有必要,一来可以保护各个国家的政见异己者,逃脱各个国家的专制压迫,普及美国人眼中的普世民主;二来能够为美国的情报人员提供信息交流的安全之所。

2003年10月,这一想法开始正式实施,为使用者提供免费的匿名网上场所。由于保护数据的密码就像洋葱一样层层包裹,这个系统最终被称为Tor(The Onion Router) https://www.ufochn.com/article-205-1.html

https://www.aqniu.com/industry/37816.html

https://parrotsec-cn.org/t/topic/50

http://blog.sina.com.cn/s/blog_63296ead0102x95x.html

http://www.theonionrouter.com/about/torusers.html.en#normalusers

http://www.thehiddenwiki.org/

下面这些网站就是火箭君在著名的thehiddenwiki.org/网站上找到的一些暗网网站 务必用Tor访问暗网(.onion结尾的网站) 务必使用https 不要用Tor登录任何网站(比如百度网盘,微博,知乎等) 不要主动发送任何关于你自己的个人信息

https://www.ufochn.com/article-205-1.html