0%

2018年4月20日 下午7:36

对于React的简单学习
simditor组件的使用方法:
FormData上传文件报错”Uncaught TypeError: Illegal invocation”
react中的时间戳转换成年-月-日 时:分:秒

学会Hogan,就那么几句

面包屑🍞的实现原理
Html-webpack-plugin的作用
webpack.config.js如何指明html<—>js之间的组合关系

后台管理员系统简介ppt
线上环境配置与项目自动化发布

后台管理系统的安装
github上的mmall-fe代码
前端项目代码环境搭建并运行

中期总结
Font Awesome
简单例子运用webpack

字段验证+统一跳转
模板和数据拼接
URL路径工具
通过网络请求工具访问后端接口
封装网络请求工具

webpack-dev-server
html-webpack-plugin
webpack打包css
webpack三种引入jquery的方法
在sublime中简单使用webpack
webpack安装(own)
脚手架的搭建
git安装配置别名+简单使用
npm入门
前后端数据交互的演进
webpack入门
正则
http代理辅助开发charles
chrome调试工具
git下载安装
node.js安装
sublime的简单使用
第1章 课程介绍与开发前的准备工作

2018年4月20日 下午7:35

注:这里有有我自己的截图




处理网络连接的中间件






注:我下载的时候已经是4.9.1了


注:这张图是我自己nodejs的默认安装地址!

注:说明更新安装成功

2018年4月19日 下午3:54
Minimum Window Substring - LeetCode

  1. 表面上我们遍历的的是string::s中的一个个元素,其实这一个个元素代表着“以这个元素结尾的一个【满足题目要求】的一个子串”。——76
    1. 这时我们就可以说:我们遍历的“元素”,变成了一个个的[满足要求]的子串
  2. 这里的数据结构很巧妙:
    1. 怎样能看出巧妙?某一个操作能用当前选择的数据结构直接实现,而不用在写循环呀、判断呀啥的。
    2. 我们这里的两个int[128] map,就是可map_s[begin_ch] > map_t[begin_ch]直接比较
    3. 并且还可以结合vector作为int[128]map的下标。map_s[vec_t[i]] < map_t[vec_t[i]]
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
//这个是老师的代码,我就不提交了

//这道题双指针遍历s,并且i是稳定+1的,而另个指针window_begin的变化是不确定的。
//也只有这样才可以用来求不确定位置和长度的最小窗口。
class Solution {
private:
//根据字符的数量来判断是否可以构成一个窗口
bool is_window_ok(int map_s[], int map_t[], std::vector<int> &vec_t){
for (int i = 0; i < vec_t.size(); i++){
if (map_s[vec_t[i]] < map_t[vec_t[i]]){
return false;
}
}
return true;
}
public:
std::string minWindow(std::string s, std::string t) {

// 这些数据结构的设置,是围绕我最上面所说的说指针遍历。是为执行双指针遍历时可以简洁快速的判断而设置的。
const int MAX_ARRAY_LEN = 128;
int map_t[MAX_ARRAY_LEN] = {0};
int map_s[MAX_ARRAY_LEN] = {0};
std::vector<int> vec_t;
//给t做一个统计,统计每个字符出现的次数
for (int i = 0; i < t.length(); i++){
map_t[t[i]]++;
}
for (int i = 0; i < MAX_ARRAY_LEN; i++){
if (map_t[i] > 0){
vec_t.push_back(i);
}
}

int window_begin = 0;
std::string result;

for (int i = 0; i < s.length(); i++){
//给s做统计,统计每个字符出现的次数
map_s[s[i]]++;

//找到window_begin的位置,判断从window_begin ~ i 之间的是否满足了t的要求
while(window_begin < i){
//取出当前s中我们正在操作的字符
char begin_ch = s[window_begin];
if (map_t[begin_ch] == 0){//当前字符不在t中
window_begin++;
}
else if (map_s[begin_ch] > map_t[begin_ch]){//当前,s中统计的个数要比t中个数多
map_s[begin_ch]--;
window_begin++;
}
else{//其他情况,window_begin维持不动,等待i的扩大,添加新元素之后进行再次的判断。
break;
}
}
//判断从window_begin ~ i 之间的是否满足了t的要求
if (is_window_ok(map_s, map_t, vec_t)){
int new_window_len = i - window_begin + 1;
if (result == "" || result.length() > new_window_len){
result = s.substr(window_begin, new_window_len);
}
}
}
//我专门提交错误
// return result;
}
};

2018年4月17日 下午3:54
Group Anagrams - LeetCode

  1. 这道题就是典型的边遍历的同时,我们要做比较复杂的判断,不同的判断下处理方式不同。
  2. 这里的关键是是使用map来记录我们遍历的过程,或者说遍历的同时维护这map,来保存我们遍历的效果。
  3. 那么我们如何查看我们的记录(map),这里面最关键的一句话就是str_map.find(str) == str_map.end()
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
class Solution {
public:
std::vector<std::vector<std::string>> groupAnagrams(std::vector<std::string>& strs) {
std::map<std::string, std::vector<std::string> > str_map;
std::vector<std::vector<std::string>> vec;
if(strs.size() == 0) return vec;

//遍历strs
for(int i = 0; i < strs.size(); i++){
//预处理
std::string str = strs[i];
std::sort(str.begin(), str.end());

//是否出现过
if(str_map.find(str) == str_map.end()){
std::vector<std::string> temp_vec;
temp_vec.push_back(strs[i]);
str_map[str] = temp_vec;
}
else{
str_map[str].push_back(strs[i]);
}
}

//遍历str_map的值放入到vec中返回
std::map<std::string, std::vector<std::string> > ::iterator it;
for(it = str_map.begin(); it != str_map.end(); it++){
vec.push_back((*it).second);
}
return vec;
}
};

2018年4月16日 下午3:54
Binary Tree Right Side View - LeetCode

  1. 遍历的对象是一个边建立边遍历的队列
    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
    class Solution {
    public:
    std::vector<int> rightSideView(TreeNode* root) {
    std::queue<std::pair<TreeNode*, int>> Q;
    std::vector<int> vec;
    //int代表这层数
    std::pair<TreeNode*, int> temp_pair;
    temp_pair.first = root;
    temp_pair.second = 0;
    Q.push(temp_pair);

    generate(Q, vec);

    return vec;

    }
    private:
    //这回同样是遍历,但是遍历的对象不是树,而是队列
    //对于队列来说,我们即放入也拿出
    void generate(std::queue<std::pair<TreeNode*, int>> &Q, std::vector<int> &vec){
    if(Q.empty()){
    return;
    }
    //当前
    std::pair<TreeNode*, int> current = Q.front();
    Q.pop();

    if(Q.empty() || current.second != Q.front().second){
    vec.push_back((current.first)->val);
    }
    //给队列添加
    std::pair<TreeNode*, int> temp_pair;
    if((current.first)->left){
    temp_pair.first = (current.first)->left;
    temp_pair.second = current.second+1;
    Q.push(temp_pair);
    }

    if((current.first)->right){
    temp_pair.first = (current.first)->right;
    temp_pair.second = (current.second+1);
    Q.push(temp_pair);
    }
    //遍历下一个
    generate(Q, vec);

    }
    };