链表的倒数第k个节点
题目:输入一个链表,输出该链表的倒数第 $k$ 个节点。为了符合大多数人的习惯,本题从 $1$ 开始计数,即链表的尾节点是倒数第一个节点。例如,一个链表有 $6$ 个节点,如下 1->2->3->4->5->6,这个链表的倒数第 $3$ 个节点是值为 $4$ 的节点。链表的定义如下:
private static class ListNode { public ListNode next; public int value; public ListNode(int value) { this.next = null; this.value = value; }}
我们的第一个思路就是先遍历链表,直到结尾,接着回溯 $k - 1$ 步即可获得倒数第 $k$ 个节点
但是从上面链表的定义可以看出,该链表是一个单向的链表,我们根本无法进行回溯。
所以我们自然的想到了第二种办法,首先遍历一遍链表,并且统计链表中节点的个数 $n$,这样我们只要向前走 $n - k$ ...
链表中环的入口节点
如何链表中包含环,如何找出环的入口节点? 例如,在如图所示的链表中,环的入口节点是节点 $3$。
解决这道题的思路分为两步,第一步是确定该链表有没有环,我们定义两个指针,一个快指针,一个慢指针,快指针一次性走两步,慢指针一次性走一步。如果有环的话,那么快指针和慢指针就会相遇,并且是在环内相遇;如果没有环的话,那么快指针就会到达尾节点,慢指针与快指针不会相遇。
public static ListNode meetingNode(ListNode root) { if (root == null) { return null; } // 慢指针先走一步 ListNode slow = root.next; if (slow == null) { return null; } // 快指针先走两步 ListNode fast = slow.next; while (slow != null && fast != null) { ...
表示数值的字符串
题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串 +100, 5e2, -123, 3.14e+1 都表示数值,而 12e, 1a3.12, 1.2.3, +-5 都不是。
首先我们要明白数值的格式为 A.B[e|E]C,其中 A, B, C 代表的是数字,有一点不同的是 A, C 中的前方可以有正负号,而 B 不能有正负号。我们变成的思路便是,首先扫描字符串,看是否匹配 A,即字符串的前方是否是数字(可包含正负号),接着如果碰到小数点,则扫描小数点后的字符是否是数字(不能包含正负号);最后匹配科学计数法,如果碰到 e|E,那么扫描后面的字符是否是数字(可包含正负号)。
代码如下:
public class IsNumberic { // 全局变量,控制从哪里开始扫描字符串 private static int index; public static boolean isNumberic(char[] str) { if (str == null) { return ...
二进制中1的个数
题目:请实现一个函数,输入一个整数,输出该数二进制表示中 $1$ 的个数。例如,把 $9$ 表示成二进制是 $1001$,有 $2$ 位是 $1$。因此,如果输入 $9$,则该函数输出 $2$。
我们通过将数字与 $1$ 相与,即可知道数字的二进制的最后一位是否为 $1$,我们只要逐渐的将数字进行右移,即可统计出数字中 $1$ 的数目,所以会写下这样的代码
public static int numbersOfOne(int n) { int count = 0; while (n != 0) { if ((n & 1) != 0) { count++; } n = n >> 1; } return count;}
但是上面的代码有一个问题,那就是如果输入的整数为负数呢? 根据负数的表示原则,它的首位是 $1$ 来表示数字的正负性,在右移的过程中,首位会进行补 $1$ 以表示它的符号还是负的,这个时候统计出的数字就 ...
offsetX,pageX,clientX和screenX
在使用的 JavaScript 的过程中,对 offset,page,client 等等所表示的距离一直不是很清楚,现趁有时间系统的学习了一下。上面所述的 offsetX,pageX 等等都是事件对象 event 的属性,当有鼠标事件触发时,可以获得相应的事件对象,该对象中包含着鼠标的各种距离,现总结如下
offsetX:离触发事件元素左边的距离
pageX:离页面左边的距离
clientX:离浏览器左边的距离
screenX:离电脑显示器左边的距离
现在就演示一下,假设有下面的页面结构
上图已经基本可以明白 offsetX 和 clientX的大小,如果没有横向的滚动条的话,pageX 与 clientX 的大小是一样的。如果有滚动条的话,那么 pageX 的距离一般是大于 clientX 的距离的,如下
上图应该已经阐释了 pageX 与 clientX 的不同,那么只剩最后一个 screenX,这个也较好理解,就是鼠标位置离电脑显示器左侧的位置,如果浏览器是最大化的话,屏幕的左侧与浏览器的左侧相同,那么 screenX 的大小与 clientX 的大小相同,如果不是最 ...
TypeScript入门指南
介绍TypeScript是什么TypeScript 是什么? 引用官方的定义
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open source.
简单翻译就是
TypeScript 是 JavaScript 的超集,并且可以被编译成 JavaScript。它可以运行在任何浏览器,任何主机,任何操作系统上。并且它是开源的。
看到这里你可能对 TypeScript 还是没有什么感觉,其实在我看来 TypeScript 是对 JavaScript 做了各种限制,这里说的限制并不是贬义的意思,因为 JavaScript 实在是太灵活了,很多的问题只有在运行的时候才会暴露出来,比如对于函数,即使定义时要求传两个参数,但是在使用时却可以传入任意的参数,所以你无法限制使用该函数的用户传入正确的参数,如果碰到不仔细看 API 文档的用户,鬼知道它使用的时候会传入什么,出了问题说不定会甩锅你兼容性做的不好。而 Type ...
JavaScript之正则表达式
在字符串的处理中,我们经常要进行字符串的匹配,校验等等操作。比如校验字符串的格式是否符合邮箱,电话号码的格式,校验密码是否符合要求,密码中是否包含数字和字母等等;又或者匹配得到某种规则的字符串。这一些操作如果使用常规的方法进行字符串操作,会花费较大的代价,包括时间和精力。
正则表达式是用来表达字符串的规则,它可以检验字符串是否符合某个特定的规则,或者匹配字符串中符合规则的字符,在一般的使用中,正则表达式一般用来匹配字符串中的字符或者字符串中特定的位置。
正则对象JavaScript 正则对象的创建有两种常见的方法,一是使用 RegExp 构造函数进行创建,二是使用字面量的方法进行创建,如下
let regex1 = new RegExp('hello', 'g');let regex2 = /hello/g;
其中 hello 表示字符串的规则,用来匹配字符串中的"hello",g 表示进行全局匹配(global),像这样的标志还有两个,m 表示进行多行匹配(multiline),i 表示忽略大小写(ignoreCase), ...
Spring常见注解
介绍 Spring 框架中的常见注解(NO XML),在介绍 Spring 注解之前,简要的介绍一下 IoC。
IoC简要介绍IoC(Inverse of Control) 的意思是控制反转,意思就是控制权发生转换,以前我们需要某个类的对象,都是直接 new 出来的,现在有了 IoC,对象创建的控制权交给 Spring,如果我们需要某个对象,向 IoC 容器拿,如下
上面将 Dog 类对象放入容器的过程我们成为注入,容器我们一般称为 IoC 容器或者 Spring 容器。上面做的好处可以减少类与类之间的耦合性,耦合性这个词可能高大尚,我举个例子,比如 Dog 类发生了改变,高耦合性意味着如果有类依赖 Dog 类的话,那么相应的该类有可能也要发生改变,如果耦合度低的话,也就是根本察觉不到自己依赖了 Dog 类,根本就不需要改变。
我们在像容器要某个对象时,察觉不到某个类的所在(因为一般使用接口去接收从容器中拿的对象),比如
Animal animal = ioc.getObject('dog');
假设 Dog 实现了 Animal 接口,ioc 对象表示 Io ...
Ajax跨域
同源策略什么是同源策略:同 domain(或IP),同端口,同协议视为同一个域,一个域内的脚本仅仅具有本域内的权限,可以理解为本域脚本只能读写本域内的资源,而无法访问其它域的资源,这种安全限制称为同源策略。我们看几个例子判断两个链接是否是同源
url1
url2
是否同源
原因
http://example.com:8080
http://example.com:80
否
端口不同
http://example.com:8080
https://example.com:8080
否
协议不同
http://www.baidu.com
http://www.taobao.com
否
域名不同
http://127.0.0.1:8080
http://localhost:8080
否
域名与域名对应的IP地址不同源
http://example.com:8000/a.js
http://example.com:8000/b.js
是
协议,域名,端口相同,子域名不同
我们首先启动一个 Node 程序作为服务端,启动在本地的 4000 端口,如下
const ...
JavaScript柯里化
柯里化介绍函数柯里化指的是函数处理一部分的参数,然后返回一个函数来处理剩余的参数,如比如有一个加法函数如下
function add(x, y) { return x + y;}add(1, 2); // 3
现在如果这个函数被柯里化,那么我们可以如下使用
const increment = add(1); // 接收第一个参数,返回一个函数处理第二个参数increment(2); // 3increment(4); // 5
柯里化实现现在怎么实现这种效果,如果只是针对上面的加法函数,那么可以如下实现
function add(x, y) { return function(y) { return x + y; }}
但是这种方法明显只对加法函数有效,我们现在是想设计一个函数,它接收一个函数为参数,作用就是把这个函数柯里化,并将这个柯里化的函数返回,比如
curryAdd = curry(add); // 接收add函数,将函数add柯里化const increment = curryA ...