Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
When I saw this problem, my first thought was to go through all of the prices and find the min and max in O(n) time and compute the maximum profit with (max - min).
However, this idea is wrong. Let’s see the following graph.
The min and max of this sotck price graph is min2 and max1. But (max1 - min2) is not what we want since we can’t sell a stock before buy it(max1 is before min2).
Then I try to solve it using Dynamic Programming.
Let OPT(i, k) denotes the maximum we get at day k if we buy the stock at day i.
Let $P_i$ denotes the price of stock at day i.
Let optTal denotes the maximum we get.
Then we have:
$ OPT(i, k) = \begin{cases} OPT(i, k - 1) & \text{not sell at day k} \\ P_k - P_i & \text{sell at day k} \end{cases} $and the optimal:
$ \begin{align} optTotal = max\{OPT(i, j)\} \\ 1 \le i \le n \\ i \le j \le n \end{align} $With this formula, we can calculate the correct answer in $O(n^2)$ time.
However, this solution is not efficient and will exceed the time limit of LeetcodeOJ.
We can go through all of the prices and update the min. Compute the profit we can get at day i by calculate ($P_i$ - min), update the max if we get a higher profit.
The complexity is O(n).
This solution works great!
1 | /** |
1 | /** |
]]>Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
Dynamic Programming problem.
Since the houses are arranged in circle, we should take the first house and the last house specially. Because if we rob the first one, we can’t rob the last one since it’s the neighbor of the first one.
So there are only two special cases:
For case 1, the problem turns into a #198 House Robber problem of 1 … n-1 houses.
For case 2, the problem turns into a #198 House Robber problem of 2 … n houses.
Compute the maximum amount of both cases and return the larger one.
For n houses, let OPT(n) denotes the maximum amount we can rob, let Vi denotes the money that the ith house holds.
For the nth house, we have two cases, rob or not rob.
It means that if we rob the nth house, we can only rob the (n-2)th house next, if we don’t rob the nth house, then we can rob the (n-1)th house next.
n means the total number of houses.
1 | /** |
]]>After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
使用 Hexo 部署博客到 Github Pages 时经常会遇到文件夹大小写问题导致的 404问题。
譬如 Hexo 生成了一个 Hackerrank in JS
Category文件夹,但是我后来把它改成了 Hackerrank In JS
,即 in 的首字母大写了。Hexo会生成正确,但部署到 Github 上却老是不正确。
git 默认忽略文件名大小写,所以即使文件夹大小写变更,git 也检测不到。
.deploy_git
文件夹,修改 .git
下的 config
文件,将 ignorecase=true
改为 ignorecase=false
1 | cd .deploy_git |
.deploy_git
文件夹下的所有文件,并 push 到 Github 上, 这一步是清空你的 github.io 项目中所有文件。1 | git rm -rf * |
1 | cd .. |
使用 Hexo 部署博客到 Github Pages 时经常会遇到文件夹大小写问题导致的 404问题。
譬如 Hexo 生成了一个 Hackerrank in JS
Category文件夹,但是我后来把它改成了 Hackerrank In JS
,即 in 的首字母大写了。Hexo会生成正确,但部署到 Github 上却老是不正确。
git 默认忽略文件名大小写,所以即使文件夹大小写变更,git 也检测不到。
]]>You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
Dynamic Programming problem.
For n houses, let OPT(n) denotes the maximum amount we can rob, let Vi denotes the money that the ith house holds.
For the nth house, we have two cases, rob or not rob.
It means that if we rob the nth house, we can only rob the (n-2)th house next, if we don’t rob the nth house, then we can rob the (n-1)th house next.
n means the total number of houses.
1 | /** |
]]>You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
1 | /** |
递归方式运行时间:
1 | /** |
循环方式运行时间:
理论上循环是比递归快的,因为同样是线性时间复杂度,递归调用需要频繁的进行栈操作,而循环不需要。
]]>]]>You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
上周参加了学校的 Career Fair,想锻炼下面试技巧和口语能力,为下学期找暑期实习做点准备。那天整条路都是熙熙攘攘的面试官和学生,Facebook、Amazon、Microsoft、eBay 这些大公司尤其火爆,有的人排了几个小时才面试上。
因为我刚来 USC 两个月,实力不够,而且大公司又有冷冻期(一次没有录上半年内不再面试),所以我也没敢投大公司,挑了几个看起来不错的小公司试试水。一共投了五个,拿到 Percolate 和 Paypal 两家的 Coding Challenge,还有一家 Demand Media 说是非常喜欢我,之后会打电话让我去 onsite interview(为啥现在还没打电话!)。
这道题是 Percolate 的题,名字叫 Funky Rolodex(复杂的关系网) 并没有考算法,而是非常贴近实际需求,处理文本文件,筛选出正确的数据解析并输出成JSON格式。虽然并不难,但是需要注意的小细节不少,譬如输出结果要按照相应地缩进,要对数据按照 Lastname 和 Firstname 排序。我之前没有注意到排序这一点,导致后来重构了一些代码,而且对我来说,排序这里是最难的(后面会解释)。
总体来说这是一道非常好的非算法题,考到了JSON,正则表达式,面向对象编程,字符串比较等等,而且这道题非常考察细心程度。
You’re tasked with taking entries of personal information in multiple formats
and normalizing each entry into a standard JSON format. Write your formatted,
valid JSON out to a file with two-space indentation and keys sorted
alphabetically.
Your program will be fed an input file of n lines. Each line contains “entry”
information, which consists of a first name, last name, phone number, color,
and zip code. The order and format of these lines vary in three separate
ways.
The three different formats are as follows:
Some lines may be invalid and should not interfere with the processing of
subsequent valid lines. A line should be considered invalid if its phone
number does not contain the proper number of digits.
The program should write a valid, formatted JSON object. The JSON
representation should be indented with two spaces and the keys should be sorted
in ascending order.
Successfully processed lines should result in a normalized addition to the list
associated with the “entries” key. For lines that were unable to be processed,
a line number i (where 0 ≤ i < n) for each faulty line should be appended to
the list associated with the “errors” key.
The “entries” list should be sorted in ascending alphabetical order by (last
name, first name).
The complete output schema is specified below.
For the input
1 | Booker T., Washington, 87360, 373 781 7380, yellow |
we should receive the output1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22{
"entries": [
{
"color": "yellow",
"firstname": "James",
"lastname": "Murphy",
"phonenumber": "018-154-6474",
"zipcode": "83880"
},
{
"color": "yellow",
"firstname": "Booker T.",
"lastname": "Washington",
"phonenumber": "373-781-7380",
"zipcode": "87360"
}
],
"errors": [
1,
3
]
}
1 | process.stdin.resume(); |
1 | /** |
上周参加了学校的 Career Fair,想锻炼下面试技巧和口语能力,为下学期找暑期实习做点准备。那天整条路都是熙熙攘攘的面试官和学生,Facebook、Amazon、Microsoft、eBay 这些大公司尤其火爆,有的人排了几个小时才面试上。
因为我刚来 USC 两个月,实力不够,而且大公司又有冷冻期(一次没有录上半年内不再面试),所以我也没敢投大公司,挑了几个看起来不错的小公司试试水。一共投了五个,拿到 Percolate 和 Paypal 两家的 Coding Challenge,还有一家 Demand Media 说是非常喜欢我,之后会打电话让我去 onsite interview(为啥现在还没打电话!)。
这道题是 Percolate 的题,名字叫 Funky Rolodex(复杂的关系网) 并没有考算法,而是非常贴近实际需求,处理文本文件,筛选出正确的数据解析并输出成JSON格式。虽然并不难,但是需要注意的小细节不少,譬如输出结果要按照相应地缩进,要对数据按照 Lastname 和 Firstname 排序。我之前没有注意到排序这一点,导致后来重构了一些代码,而且对我来说,排序这里是最难的(后面会解释)。
总体来说这是一道非常好的非算法题,考到了JSON,正则表达式,面向对象编程,字符串比较等等,而且这道题非常考察细心程度。
]]>Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.
For example:
Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it.
1 | /** |
]]>Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.
For example:
Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it.
今天早上因为罪恶感奋发图强,早早起来开始背单词。背之前想先听一下WordList 3的单词音频,所以用手机对着红宝书WordList上的二维码扫了一下,进入网页听录音(新东方真是与时俱进呀!都用上二维码了!!)。
听了一会,突发奇想,何不把所有WordList的音频都下下来装在手机里呢,这样随时都可以听!于是开始笨拙的把微信里的网页链接分享到电脑上,然后用浏览器一个一个的下载,下了几个感觉不对劲。。。太麻烦了,这种重复性的工作干嘛要自己做!!交给计算机就好了嘛!
so,我写了个nodejs
程序批量的下载,不到1分钟,42个list的录音就都进入了我的硬盘。 ; )
首先是github 项目地址,取名为 getGreWordListTapes
~
红宝书里的二维码所包含的信息就是音频的链接,链接的形式如下:
1 | http://download.dogwood.com.cn/online/grechjx/WordList01.mp3 |
很容易看出,末尾就是WordList01.mp3,代表第1个单词表的音频,随便改了下那个数字,改成02,03,..,42等,都能访问对应的单词表的音频。
所以批量下载就是从01循环到42,就能下载所有的单词表的音频啦。
其实本身也很简单,按照流程图很快就能做出来,但是有一些需要注意的地方。譬如:
nodejs 的 http
模块的 get
方法可以帮助我们请求目标url,并获取返回的数据,但是数据不是一次性返回的,而是一段( chunk
)一段的来的,因此我们需要在 get
方法的回调函数里对 http response的 data
事件进行监听,并对获取到的数据段进行文件的 append 操作。
nodejs 可以并发的下载,而且各个文件的下载并不是按顺序来的。但是文件的写入是按顺序并且是同步的写入的,不然就会出现文件错乱。因此我采用了 fs
模块的 appendFileSync
方法。
需要对音频文件是否存在进行判断,不然就会出现第二次运行下载程序的时候,会在之前下载过的文件后继续append。 这是个逻辑问题,哈~
1 | var http = require('http'), |
使用 chalk 模块添加了下图中的终端高亮效果,嘿嘿~
最后,把所有的音频添加到itunes中做成专辑,加上封面~
]]>今天早上因为罪恶感奋发图强,早早起来开始背单词。背之前想先听一下WordList 3的单词音频,所以用手机对着红宝书WordList上的二维码扫了一下,进入网页听录音(新东方真是与时俱进呀!都用上二维码了!!)。
听了一会,突发奇想,何不把所有WordList的音频都下下来装在手机里呢,这样随时都可以听!于是开始笨拙的把微信里的网页链接分享到电脑上,然后用浏览器一个一个的下载,下了几个感觉不对劲。。。太麻烦了,这种重复性的工作干嘛要自己做!!交给计算机就好了嘛!
so,我写了个nodejs
程序批量的下载,不到1分钟,42个list的录音就都进入了我的硬盘。 ; )
首先是github 项目地址,取名为 getGreWordListTapes
~
下面我说说制作过程
]]>
Connect is a middleware framework for node.
Connect 是 nodejs 的中间件框架。何为中间件?中间件就是用户请求和返回结果之间的一个又一个筛选工具。正如 @Luics 所说“如果把一个http处理过程比作是污水处理,中间件就像是一层层的过滤网。”
中间件能在请求用户请求处理之前,进行一些预处理,而在返回结果之前,又进行一些返回之前的处理。非常类似于洋葱模型,一层一层的进入,又一层一层的退出。
Connect中间件的处理流程如下:
nodejs 中,http server 有两个参数传入,分别是 request 和 response 代表请求和响应结果,这两个参数也会被传入中间件中。此外,connect 中间件还有第三个参数:next 函数。通常使用该参数的方法是:next();
。因此大家常认为 next 代表下一个中间件函数,但事实上,next 只是 connect 生成的一个函数,它的作用是告诉 connect 可以调用下一个中间件来处理 request 和 response 了。如果下一个中间件,则调用,如果不存在,就没有调用了。
参考:更多关于 conncet 的介绍请访问以下链接:
看完简介和一些深入的介绍之后,我们就可以开始着手做一个自己的中间件来方便我们的 web 开发了。
实践才是最好的老师,不踩坑就不能深入理解。
现在笔者有这么一个需求:在本地进行 demo 页面开发的时候,对静态页面进行模块式开发,实现 html 页面之间的引用。譬如,做一个公用的 header 或者 footer ,以便其他页面进行引用。
在没有 nodejs 之前,可以通过对 Apache 服务器进行一些配置,以支持 `SSI(Server Side Include)‘ 命令。通过类似
1 | `<!--#include virtual="./mod/header.html"-->` |
的命令来实现引用。
现在在 nodejs 环境下开发,就没有了这种支持。所以我们要自己动手,丰衣足食。没有的,我们就自己创造工具。
要实现的功能非常简单——当服务器收到对 html 文件的请求时,将请求的 html 文件中的类似 <!--#include virtual="./mod/header.html"-->
的字符串替换成对应模块的 html 代码,然后将请求的内容返回给浏览器。
流程图如下:
中间件的接口,即为中间件调用者可以配置的参数。通过参数配置来使中间件正常工作,和动态定制。
这里我们需要考虑几个问题:
#include
的文件?以上几个问题是从功能设计中的流程图所分析出来的,也是我们实际编码时必须要解决的问题。
#include
中的被引用 html 文件路径通常是相对于引用 html的,所以我们可以将应用 html文件路径和被应用文件的路径组合起来即可综合上面几点,我们可以拟定以下接口:
1 | // 传入中间件的配置对象option: |
中间件都是node的扩展模块,好的模块应该有清晰的代码组织方式。我们可以参考一下 connect、express等模块的组织方式,通常都是采用以下结构:
1 | - moduleName/ |
即采用
设置模块名称、介绍、版本、依赖的模块信息等等,由于本中间件全部采用 nodejs 内置模块,因此没有设置模块依赖 dependencies
。
在这里,我给我的模块去了一个名字:connect-ssiinclude
,标识它是一个基于 connect 的中间件,作用是支持 ssi 命令中的 include 。
1 | // package.json |
更多关于 package.json 的配置见:npm doc package.json
nodejs 的模块系统的机制是,模块引用时,默认读取模块目录下的 index.js,即 index.js 能暴露出模块的公有接口。这样在自己的程序中,引用模块时,只需要指定模块目录的路径就行了,不用关心模块的核心代码在哪里。
1 | // index.js |
该文件只有一行代码,就是 require 模块的核心代码。
这个文件就是核心代码所在了,我们需要在这里实现上面流程图中的所有逻辑。下面我们来解析下实现过程:
1 | // 内置模块的引用,分别为文件系统模块fs,路径处理模块path,url模块等 |
写完了核心代码,经过测试,就能够进行中间件发布了,让全世界的小伙伴都能用到我们的中间件。
要发布一个中间件,我们需要做下面这几件事:
一个完整的开源项目需要完善的文档说明。
我们不能写了代码就不管了,我们还需要教别人怎么用我们的代码,因此我们至少得写一个README.md
,对模块的安装、使用、配置进行简要的说明。如果模块比较复杂的话,我们还需要专门建一个 doc 目录,为使用细节撰写说明文档。广受欢迎的开源项目都是这么做的。
下面是 connect-ssiinclude 的 README.md 文件内容:
A middle ware for enable ssi include patterns in your html and shtml files. It’s very useful during developments when
you write html files in the way of modules.
It will replace pattern like <!--#include virtual="./mod/header.html"-->
with the actual header.html file and transfer
to your browser.
1 | $ npm install --save connect-ssiinclude |
1 | var include = require('connect-ssiinclude'); |
1 | include(option) // use a option object to config connect-include |
所有代码和文档准备好之后,我们就可以发布中间件了。发布到哪?npm( node package manager ,node包管理器)。
unix 下安装: 见 npm github page
1 | $ curl -L https://npmjs.org/install.sh | sh |
首次发布之前需要创建 npm 用户,需要在终端运行:
1 | $ npm adduser |
根据指示进行输入以完成创建。
创建好用户之后就可以发布了,终端运行:
1 | $ npm publish path/to/your/module // 指定你的模块文件夹路径 |
可能会出现你的模块名称已经被别人使用了等等问题,按照报错进行修改即可。
不出意外,现在你已经成功编写并在npm上发布了一个connect中间件了。
撒花~
]]>Connect is a middleware framework for node.
Connect 是 nodejs 的中间件框架。何为中间件?中间件就是用户请求和返回结果之间的一个又一个筛选工具。正如 @Luics 所说“如果把一个http处理过程比作是污水处理,中间件就像是一层层的过滤网。”
中间件能在请求用户请求处理之前,进行一些预处理,而在返回结果之前,又进行一些返回之前的处理。非常类似于洋葱模型,一层一层的进入,又一层一层的退出。
]]>公司安排的酒店在西湖区,离阿里大本营西溪园区10公里左右。好在支付宝大厦在西湖区天目山路,离酒店不远,支付宝和西溪园区之间还有公司的穿梭巴士。所以和小伙伴们约好了早上去坐7:40的穿梭巴士。
室友6点刚过就爬起床了,洗漱声把我也吵醒了。无奈起床洗漱,洗漱完才6:30。不幸福 =_=。
恰逢杭州下起了小雨,折腾了一会,总算到了支付宝大厦。坐上巴士启程。半小时左右就到了,先入职了的小伙伴领着去食堂吃了顿不错的早餐:甜!豆腐脑+贵族食品茶叶蛋+小资情调小蛋糕~
月底、毕业季直接导致了今天入职人数爆棚,同一天入职的正式员工和实习生大概280多个(话说有好多漂亮的软妹子 : P )。一行人在几个hr的带领下,浩浩荡荡的队伍来到了5号楼的报告厅,据说马总经常在这慷慨激昂的演讲。
虽然人很多,但是现场很有秩序,由于需要领取各种协议材料(每个人都不同),hr号召大家排成3纵队,材料hr事先按照姓氏首字母进行了分类,方便查找每个人的材料,每次9个人去去材料,差不多了就下一波人。取到材料后就可以按照材料上标注的序号对号入座,非常之有效率。
后续就是一些材料的核实和协议的签署,无他。
主要是西溪园区衣食住行的介绍。目前西溪园区淘宝城第一期完工,有6栋办公楼在使用。楼之间都是连同的,这意味着你可以不下楼从1号楼走到6号楼,哈哈。
1号楼、2号楼、5号楼分别有一个大餐厅。各有特色,1号楼是台湾人开的,包含中餐和西餐,是公认的最好吃的餐厅。2号楼主要是粤菜。5号楼专攻面食,当然也有其他吃的。
Ps: 在园区消费可以直接刷工牌,因为工牌是和你的支付宝账号实名绑定的,十分方便。
健身房、篮球场、羽毛球场、台球室应有尽有,更有意思的是每栋楼靠近电梯的空地上都摆了桌上足球,大家随意玩。1号楼餐厅那还有实况游戏和两个小球门供玩耍。
各种报销制度、规定。开始的视频很有意思,很没节操。后面讲内容很boring,睡着了。。
各种硬件设置、内网使用介绍。
除了工资查询之外,其他的跟实习生关系不大,但是听着还是挺不错的。尤其是iHome政策,为p5-p8的员工提供买房首付无息贷款,赞。
一整天的培训搞完已经累成狗了,为了第二天上班方便,赶紧去hr服务中心领了工牌。电脑视部门而定,台式机、笔记本等。天猫前端实习生27寸iMac不解释。哈哈哈 : P
带我的师兄很 nice,告知我各种基本情况,说给我一周时间熟悉开发环境等,再开始干点独立的小功能。只透露一句,天猫前端进行采用GULP构建。Fighting!~
]]>公司安排的酒店在西湖区,离阿里大本营西溪园区10公里左右。好在支付宝大厦在西湖区天目山路,离酒店不远,支付宝和西溪园区之间还有公司的穿梭巴士。所以和小伙伴们约好了早上去坐7:40的穿梭巴士。
室友6点刚过就爬起床了,洗漱声把我也吵醒了。无奈起床洗漱,洗漱完才6:30。不幸福 =_=。
恰逢杭州下起了小雨,折腾了一会,总算到了支付宝大厦。坐上巴士启程。半小时左右就到了,先入职了的小伙伴领着去食堂吃了顿不错的早餐:甜!豆腐脑+贵族食品茶叶蛋+小资情调小蛋糕~
]]>随着接触的技术的增多,发现前端水真是很深,代码的世界是如此美妙。我得加快步伐,追赶他们了,这个博客,也是我的每一步的见证。希望通过写文章的形式,反思、咀嚼、吸收的知识,传播技术。
这也算是一种重生吧。
]]>随着接触的技术的增多,发现前端水真是很深,代码的世界是如此美妙。我得加快步伐,追赶他们了,这个博客,也是我的每一步的见证。希望通过写文章的形式,反思、咀嚼、吸收的知识,传播技术。
这也算是一种重生]]>