动态规划-区域检索

给定一个整数数组 nums,求出数组从索引 i 到 j(i ≤ j)范围内元素的总和,包含 i、j 两点。

实现 NumArray 类:

NumArray(int[] nums) 使用数组 nums 初始化对象
int sumRange(int i, int j) 返回数组 nums 从索引 i 到 j(i ≤ j)范围内元素的总和,包含 i、j 两点(也就是 sum(nums[i], nums[i + 1], … , nums[j]))

阅读更多

Typescript的装饰器

装饰器(Decorator)模式 的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

函数装饰器

1
2
3
4
5
6
7
8
9

function sayGood(sayThing: ()=> void): (msg: string)=>void{
return function (msg: string){
console.log('say good' + msg);
sayThing();
}
}

sayGood(()=>{console.log('hello boy')})('candy');

类装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function age(target: Function) {
target.prototype.sayName = function() {
console.log("hello jonny");
};
}

@age
class Login {
public username: string = "";
public password: string = "";
}

const login: any = new Login();
login.sayName(); //"hello jonny"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function setAge(param: string) {
return function(target: any) {
target.prototype.sayName = function() {
console.log(param);
};
};
}

@setAge("Hello Candy!")
class Login {
public username: string = "";
public password: string = "";
}

const login: any = new Login();
login.sayName(); //'hello candy'

属性装饰器

1
2
3
4
5
6
7
8
9
10
11
12
function hName(param: string) {
return function(target: any, propertyName: string) {
target[propertyName] = param;
};
}

class Hello {
@hName("Jonny")
name: string;
}

console.log(new Hello().name); // 输出: Jonny

方法装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function GET(url: string) {
return function(target, methodName: string, descriptor: PropertyDescriptor) {
target.run = function() {
console.log("ok");
descriptor.value();
};
};
}

class HelloService {
constructor() {}
@GET("xx")
getUser() {
console.log("no");
}
}

const instance: any = new HelloService();

instance.run(); //ok,no

参数装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14

function PathParam(paramName: string) {
return function(target, methodName: string, paramIndex: number) {
!target.$Meta && (target.$Meta = {});
target.$Meta[paramIndex] = paramName;
};
}

class HelloService {
constructor() {}
getUser(@PathParam("userId") userId: string) {}
}

console.log((<any>HelloService).prototype.$Meta); // {'0':'userId'}

状态模式

将每个状态封装成类,通过场景进行映射相关的状态类,从而实现状态模式

下面制作一个关于灯光的场景,灯光按钮有三种状态,按每一个按钮,都会触发一个信号,并把下一个状态传递给下一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// 这是灯光状态的抽象类
abstract class LightState{
abstract state:string;
light:Light;

constructor(light:Light){
this.light = light;
}

print(){
console.log(this.state);
}

abstract changeState():void;
}

//关灯
class OffLightState extends LightState{
state:string = 'off';
constructor(light:Light){
super(light);
}
changeState(){
this.light.setState(this.light.weakState);
}
}

//暖灯
class WeakLightState extends LightState{
state:string = 'weak';
constructor(light:Light){
super(light);
}
changeState(){
this.light.setState(this.light.strongState);
}
}

//强灯
class StrongLightState extends LightState{
state:string = 'strong';
constructor(light:Light){
super(light);
}
changeState(){
this.light.setState(this.light.offLightState);
}
}

class Light{
offLightState:OffLightState = new OffLightState(this);
weakState:WeakLightState = new WeakLightState(this);
strongState:StrongLightState = new StrongLightState(this);
currentState:LightState = this.offLightState;

setState(newState:LightState){
this.currentState = newState;
}

//点击事件
onPress(){
this.currentState.print();
this.currentState.changeState();
}
}

let light = new Light();

light.onPress();//off
light.onPress();//weak
light.onPress();//strong

关于排序的三种算法

  • 算法

冒泡排序

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。

它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。

这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 let bubbleSort = function (arr:number[]):number[]{
let temp:number = 0;
for(let i = 0;i<arr.length;i++){
for(let j = 0;j<arr.length;j++){
if(arr[i]<arr[j]){
let temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
return arr;
}
let result = bubbleSort([4,5,6,7,2,9,7,9,7,56,45,4,34,3,3,1]);

阅读更多

享元模式

享元模式的核心是共享对象,目的是节省内存开销,分为三个场景,共享对象的内部状态、共享对象的工厂函数、共享对象的外部函数。以共享单车为例,如下

阅读更多

模版方法

模版方法是指在父类搭建算法框架,通过子类继承这些算法框架,并调用父类的模版方法对算法框架进行调用,特别是解决众多类具有很多相同算法,只有少量不同的场景

例如泡茶与泡咖啡都有很多相同的流程,只是细节有些差异,就可以通过模版方法进行归纳

阅读更多

观察者模式

通常说对于事件的监听并触发回调函数就是观察者模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

// 引入 events 模块
const EventEmitter = require('events');
// 创建 eventEmitter 对象,这就是可观察对象
const myEmitter = new EventEmitter();

//观察者
function obs(...args){
console.log(args.join(','));
}

// 订阅
myEmitter.on('event',obs);

// 发布
setTimeout(function() {
myEmitter.emit('event',1,2,3)
}, 1000);

//取消发布
myEmitter.removeListener('event',obs);

代理模式

当客户程序不断地访问本体程序,会产生副作用,譬如垃圾请求、不符合规范的请求,或者是本体程序尚未做好准备,所以需要通过代理的规范请求内容,过滤不符合要求的请求,这就是代理模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

//本体程序返回数字的倍数
var A = function (num){
return num*2;
}

//代理程序,检查输入的是不是数字
var B = function (num){
if(typeof num !== 'number'){
console.log('你输入的不是数字');
return false;
}else{
A(num);
}
}

//客户程序
(function (){
B(3); //6
B('3') //error
})()

阅读更多

策略模式

策略模式分为两部分,一部分是环境类,另一部分是策略类,环境类是接受命令的入口,策略类是无数策略的集合,通过策略模式将环境类与策略类连通,在环境的策略方法中可以自由替换策略

阅读更多