Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wushizhenking
CS-Notes
提交
1a478a90
C
CS-Notes
项目概览
wushizhenking
/
CS-Notes
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
CS-Notes
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
1a478a90
编写于
12月 08, 2018
作者:
C
CyC2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
auto commit
上级
f636f9c8
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
10 addition
and
60 deletion
+10
-60
notes/Java IO.md
notes/Java IO.md
+1
-1
notes/Java 基础.md
notes/Java 基础.md
+8
-6
notes/Java 并发.md
notes/Java 并发.md
+1
-1
notes/代码风格规范.md
notes/代码风格规范.md
+0
-3
notes/剑指 offer 题解.md
notes/剑指 offer 题解.md
+0
-49
未找到文件。
notes/Java IO.md
浏览文件 @
1a478a90
...
...
@@ -122,7 +122,7 @@ DataInputStream 装饰者提供了对更多数据类型进行输入的操作,
UTF-16be 中的 be 指的是 Big Endian,也就是大端。相应地也有 UTF-16le,le 指的是 Little Endian,也就是小端。
Java
的内存编码
使用双字节编码 UTF-16be,这不是指 Java 只支持这一种编码方式,而是说 char 这种类型使用 UTF-16be 进行编码。char 类型占 16 位,也就是两个字节,Java 使用这种双字节编码是为了让一个中文或者一个英文都能使用一个 char 来存储。
Java 使用双字节编码 UTF-16be,这不是指 Java 只支持这一种编码方式,而是说 char 这种类型使用 UTF-16be 进行编码。char 类型占 16 位,也就是两个字节,Java 使用这种双字节编码是为了让一个中文或者一个英文都能使用一个 char 来存储。
## String 的编码方式
...
...
notes/Java 基础.md
浏览文件 @
1a478a90
...
...
@@ -1210,18 +1210,20 @@ Class 和 java.lang.reflect 一起对反射提供了支持,java.lang.reflect
-
**Constructor**
:可以用 Constructor 创建新的对象。
**反射的优点:**
-
**可扩展性**
:应用程序可以利用全限定名创建可扩展对象的实例,来使用来自外部的用户自定义类。
-
**类浏览器和可视化开发环境**
:一个类浏览器需要可以枚举类的成员。可视化开发环境(如IDE)可以从利用反射中可用的类型信息中受益,以帮助程序员编写正确的代码。
-
**调试器和测试工具**
: 调试器需要能够检查一个类里的私有成员。测试工具可以利用反射来自动地调用类里定义的可被发现的API定义,以确保一组测试中有较高的代码覆盖率。
*
**可扩展性**
:应用程序可以利用全限定名创建可扩展对象的实例,来使用来自外部的用户自定义类。
*
**类浏览器和可视化开发环境**
:一个类浏览器需要可以枚举类的成员。可视化开发环境(如 IDE)可以从利用反射中可用的类型信息中受益,以帮助程序员编写正确的代码。
*
**调试器和测试工具**
: 调试器需要能够检查一个类里的私有成员。测试工具可以利用反射来自动地调用类里定义的可被发现的 API 定义,以确保一组测试中有较高的代码覆盖率。
**反射的缺点:**
尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。在我们使用反射技术时,下面几条内容应该牢记于心。
-
**性能开销**
:反射涉及了动态类型的解析,所以JVM无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。
-
**安全限制**
:使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如Applet,那么这就是个问题了。
-
**内部暴露**
:由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用,这可能导致代码功能失调并破坏可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。
*
**性能开销**
:反射涉及了动态类型的解析,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。
*
**安全限制**
:使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如 Applet,那么这就是个问题了。
*
**内部暴露**
:由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用,这可能导致代码功能失调并破坏可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。
-
[
Trail: The Reflection API
](
https://docs.oracle.com/javase/tutorial/reflect/index.html
)
...
...
notes/Java 并发.md
浏览文件 @
1a478a90
...
...
@@ -632,7 +632,7 @@ B
它们都属于 Object 的一部分,而不属于 Thread。
只能用在同步方法或者同步控制块中使用,否则会在运行时抛出 IllegalMonitorStateException。
只能用在同步方法或者同步控制块中使用,否则会在运行时抛出 IllegalMonitorStateEx
e
ception。
使用 wait() 挂起期间,线程会释放锁。这是因为,如果没有释放锁,那么其它线程就无法进入对象的同步方法或者同步控制块中,那么就无法执行 notify() 或者 notifyAll() 来唤醒挂起的线程,造成死锁。
...
...
notes/代码风格规范.md
浏览文件 @
1a478a90
...
...
@@ -4,6 +4,3 @@
-
[
Twitter Java Style Guide
](
https://github.com/twitter/commons/blob/master/src/java/com/twitter/common/styleguide.md
)
-
[
Google Java Style Guide
](
http://google.github.io/styleguide/javaguide.html
)
-
[
阿里巴巴Java开发手册
](
https://github.com/alibaba/p3c/blob/master/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8C%EF%BC%88%E8%AF%A6%E5%B0%BD%E7%89%88%EF%BC%89.pdf
)
notes/剑指 offer 题解.md
浏览文件 @
1a478a90
...
...
@@ -2826,55 +2826,6 @@ public int LastRemaining_Solution(int n, int m) {
return
(
LastRemaining_Solution
(
n
-
1
,
m
)
+
m
)
%
n
;
}
```
## 解题思路详解
创新的解法,采用数学公式推导找到规律,推导过程如下:
Step1.
首先定义一个关于 m 和 n 的函数:f(n, m),表示在n个数字 0,1,2…,n-1 中每次删除第m个数字,最后剩下的那个数字。
注意:f(n, m)表示的是,在经过了多次删除后,最后剩下的那个数字,也就是说f(n,m)本质上是个数。
Step2.
n个数中,第一个被删除的数是(m - 1) % n,把它记为k,此时数组中还剩下0,1,2… k-1, k+1,…n-1 这几个数字。接下来从k+1开始计数,相当于在剩下的序列中,k+1排在最前面,从而形成k+1,… n-1,… 0,1,2…k-1。本题中,第一个被删除的是数字2,因此数组还剩下 0,1,3,4,5,相当于3,4,5,0,1。由于这个序列是不连续的,在2那个地方断开了,所以不能写为f(n-1, m)。在此记为g(n-1, m)。
最初序列最后剩下的数字,一定是删除一个数字后剩下的数字,因此f(n, m) = g(n-1, m)
Step3.
将[3,4,5,0,1]重新映射为[0,1,2,3,4],映射的公式是:p(x) = (x - k - 1) % n。其中k = 2,n = 6。
3 —-> 0
4 —-> 1
5 —-> 2
0 —-> 3
1 —-> 4
映射以后的序列是0,1,2,3,4,是一个连续的序列,因此可以用f(n-1, m)来表示。
此时的f(n-1, m)是不等于g(n-1, m),因为二者对应的序列不同,存在一个映射关系。
该映射的逆映射是 p’(x) = (x + k + 1) % n
因此g(n-1, m) = p’[f(n-1, m)] = [f(n-1, m) + k + 1] % n
即:f(n, m) = [f(n-1, m) + k + 1] % n
带入k = (m - 1) % n, 得到f(n, m) = [f(n-1, m) +m] % n (n > 1)
Step4.
当n = 1时,只有一个人,此时剩余的数字为0
综上,约瑟夫环的公式是:
f(n, m) = 0 (n = 1)
f(n, m) = [f(n-1, m) +m] % n (n > 1)
```
java
public
class
Solution
{
public
int
LastRemaining_Solution
(
int
n
,
int
m
)
{
// 不合法输入的判断
if
(
n
==
0
||
m
<
1
)
{
return
-
1
;
}
int
last
=
0
;
for
(
int
i
=
2
;
i
<=
n
;
i
++)
{
last
=
(
last
+
m
)
%
i
;
}
return
last
;
}
}
```
# 63. 股票的最大利润
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录