对象的思路
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
var arr = [0,1,2,3,4,5,6,1,2,3,4,5,6,3,4,5,6];
function appearOnce (arr , n) {
var n = n || 1;
var obj = {};
var result = [];
for(var i = 0; i < arr.length; i++) {
if(obj[arr[i]]) {
obj[arr[i]]++;
}else {
obj[arr[i]] = 1;
}
}
for(var prop in obj) {
if (obj[prop] == n) {
result.push(prop);
}
}
return result
}
var newArr = appearOnce(arr , n);
console.log(newArr);
这么写实际上有个缺陷,
最终返回的数组中的类型都会变成 String
这个对象思路也能用于数组去重
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function appearOnce (arr) {
var result = [];
for(var i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) == arr.lastIndexOf(arr[i])) {
result.push(arr[i]);
}
}
return result
}
var newArr = appearOnce(arr);
console.log(newArr);
这个方法挺巧妙的, 但只能筛选出只出现一次的,
出现多次的就无法筛选.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var arr = [1,2,3,4,5,6,9,1,2,3,4,5,6];
function appearOnce (arr) {
var result = 0;
for(var i = 0; i < arr.length; i++) {
result ^= arr[i];
}
return result
}
var a = appearOnce(arr);
console.log(a);
这是利用了异或运算的特征
异或运算, 先把数字改成 二进制
每一位,不同为1.
特征是: a ^ a = 0
a ^ 0 = a
a ^ b ^ c = b ^ a ^ c
这里利用了, 偶数次异或相同的数字,会得0 的特征.
个人感觉,适用范围还挺狭窄的.
感觉这就是排序,找出最小值
1
2
3
4
5
6
7
8
var arr = [1,5,3,3,8,4,9,3,5];
function findMin(arr) {
var newArr = arr.slice(0);// 为了 sort 不影响原来数组
newArr.sort();
return newArr[0];
}
var a = appearOnce(arr);
console.log(a);
1
2
3
4
5
6
7
8
function appearOnce (arr) {
var min = arr[0];
for(var i = 1; i < arr.length; i++) {
min = Math.min(min, arr[i])
// 这里也可以 这样 min = min >= arr[i] ? arr[i] : min;
}
return min
}
老师为了涉及一下二分法思想,写了下面的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var arr = [5,6,7,1,2,3,4];
function searchMin (arr) {
var mid = arr[Math.floor(arr.length / 2)];
if (arr.length == 2) {
return Math.min(arr[0],arr[1]);
}
if(arr[0] >= mid) {
var arr1 = arr.slice(0,mid + 1);
return searchMin(arr1);
}else{
var arr1 = arr.slice(mid);
return searchMin(arr1);
}
}
var a = searchMin(arr);
console.log(a);//5 有问题
但这个方法问题是很多的.
1. 天然的就会假定 arr[mid] 不是最小的.
2. 如果遇到 arr[0] == mid 时, 实际上 最小值 有可能在 左侧, 也有可能在右侧.
二分法排序是可以的. 用这种方法找最小值,似乎有问题.
先贴一下烂的,
我想了40分钟, 没写出来.感觉自己似乎还是菜鸟中的菜鸟
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
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
// 先把 一维数组, 改成二维数组
// 可以改成 2*8 8*2 也可以改成 4 * 4
// 我们假设 给定的数组长度是 某个数的平方
function cons (arr) {
var newArr = [];
var len = arr.length;
var xlen = Math.sqrt(len);
var k = 0;
for (var i = 0; i < xlen ; i++) {
newArr[i] = [];
for (var j = 0; j < xlen; j++) {
newArr[i][j] = arr[k];
k++;
}
}
return newArr;
}
var newArr = cons(arr);
console.log(newArr);
// 顺时针 打印, 或者排序
function print (arr) {
var i = 0;
var j = 0;
var xlen = arr.length;
var newArr = [];
while (j != xlen){
newArr.push(arr[i][j]);
j++;
}
j = xlen - 1;
while (i != xlen){
newArr.push(arr[i][j])
i++;
}
i = xlen - 1;
while (j < 0){
newArr.push(arr[i][j]);
j--;
}
j = 0;
while (i != 1){
newArr.push(arr[i][j]);
i--;
}
i = 1;
while (j){
}
}
实在是太烂了, 写不下去.
董老师版
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
function print (arr) {
var direction = {
"RIGHT" : {
x : 1,
y : 0
},
"LEFT" : {
x : -1,
y : 0
},
"UP" : {
x : 0,
y : -1
},
"DOWN" : {
x : 0,
y : 1
}
}
var xlen = arr.length ;
var ylen = arr[0].length ;
var xMax = xlen - 1;
var yMax = ylen - 1;
var xMin = 0;
var yMin = 0;
var nowDirection = direction.RIGHT;
var x = 0;
var y = 0;
var result = [];
for(var i = 0; i < xlen * ylen; i++) {
// 装进数组
result.push(arr[y][x]);
x = x + nowDirection.x;
y = y + nowDirection.y;
// 判断临界点,改变方向.
if (x == xMax && y == yMin && nowDirection == direction.RIGHT) {
nowDirection = direction.DOWN;
console.log('down');
yMin++;
} else if (x == xMax && y == yMax && nowDirection == direction.DOWN) {
nowDirection = direction.LEFT;
console.log('left');
xMax--;
}else if (x == xMin && y == yMax && nowDirection == direction.LEFT) {
nowDirection = direction.UP;
console.log('up');
yMax--;
}else if (x == xMin && y == yMin && nowDirection == direction.UP) {
nowDirection = direction.RIGHT;
console.log('right');
xMin++;
}
}
return result
}
var lastArr = print(newArr);
console.log(lastArr);
</script>
瞬间,我就似曾相识..这是陈老师在设计模式贪吃蛇案例中写过的.
我写的和董老师写的相比之时, 突然感慨..
首先,差距是有的. 但董老师写的一看完, 实际上不难理解.
思维上的第一个飞跃是 #方向的设置. 这是空间上有了方向之后的概念. 我没有及早想到.
更关键的问题在于, 不难发现, 董老师写的代码中, 设置的变量数量是我的数倍.
变量足够多, 定义足够清晰, 整个架构就足够清晰, 思路也就越清晰.
我的问题在于,有一个思维定式. 因为前面几道题, 代码量很少, 变量很少. 注意力集中在,用更少的变量, 更巧妙的方法, 去完成需求. 觉得设置过多的变量是一种很臃肿的做法.
然后深深的感觉被打脸..
我觉得以往我写一些小案例的时候, 往往遇到很多头昏脑涨的情况时, 就跟今天的情况差不多.
总想从有限的变量,数据当中, 理出各种复杂的关系. 而实际上关系也不用太多, 只要稍微复杂一点, 我的大脑,感受到的困难程度 几何式的上升.
#总结, 对我来讲,应该走这样一种方法, 先把概念对应的,临界点对应的,关系对应的, 用变量标识出来. 根据这些变量整理完关系之后, 最后重新根据依赖关系,整理这些变量. 精简这些变量. 别耍聪明,还是这样更稳妥更有效率.