Algorithm
每周至少做一个Leetcode算法题
第1道
【题目来源】
T8:旋转数组的最小数字,何海涛《剑指Offer》
【题目】
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。
【例子】
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
【解答】
本题若读者给出顺序遍历的方案,复杂度为O(N),显然没有用到旋转数组的特性,不会是最优解
注意到有序数组这一条件,利用二分查找写出O(logN)的解法才是面试官想要的
步骤
无
【参考代码】
package com.pengluo.hht_offer.T08_RotateArray;
public class GetMinInRotateArray {
/**
* 解法1:遍历数组,逐一比较
* @param arr
*/
public int getMinInRotate1(int[] arr) {
if (arr == null || arr.length ==0) {
return -1;
}
for (int i=0; i < arr.length; i++) {
if (arr[i] > arr[i+1]){
return arr[i+1];
}
}
}
/**
* 解法2:二分查找
* @param arr
* @return arr[mid]最小值
*/
public int getMinInRotate2(int[] arr) {
if (arr == null || arr.length ==0) {
return -1;
}
int left = 0;
int right = arr.length - 1;
int mid = left;
while (arr[left] >= arr[right] ) {
//
if ( 1 == right - left) {
mid = right;
break;
}
mid = (left + right)/2;
// arr[left]=arr[mid]=arr[right]的特殊情形,单独处理,因为二分查找不能判定mid属于哪个递增数组
if (arr[left] == arr[right] && arr[left] == arr[mid]) {
return minInOrder(arr,left,right);
}
// 中间位置在左边递增数组
if (arr[mid] >= arr[left]) {
left = mid;
} else if (arr[mid] <= arr[right]) {// 中间位置在右边递增数组
right = mid;
}
}
return arr[mid];
}
// 顺序查找
private int minInOrder(int[] arr,int left, int right) {
int result = arr[left];
for (int i = left +1; i <= right; i++) {
if (result > arr[i]) {
result = arr[i];
}
}
return result;
}
}
【思考】
无
Review
阅读并点评至少1篇英文技术文章
【原文】:Jeff Atwood The Problem With Logging
【译文】:
打日志确实有某种迷人的吸引力。为什么不尽可能多的打日志呢?而且打日志对定位问题有好处,那么到处打日志,有什么坏处呢?
似乎打日志没有什么坏处,但其实可能以你严重的损害,举个例子看看
在高负载情形下,一个经典的死锁产生。我不保证你在一个轻负载的App上能看到它,但是在我们的网站平均一天一次的发生它。
我不怪log4net日志框架,我认为是我们写的垃圾代码负全责。后来我们花费了数天定位这些死锁,......。调用了很多资源,花了很大代价,最后我们确定罪魁祸首:日志策略。多么讽刺!
我从来就不是一个典型的打日志的超级粉丝
-
打日志意味着更多的代码
-
打日志并不免费
日志框架虽然高效,但不是无限快。打日志带来性能开销和增加额外的时间
-
如果值得保存到日志文件,值得在用户接口出现
-
日志用的越多,你能找到的东西越小
GB的日志数据太多了,需要花费巨大的脑力处理
-
日志文件
看到这里,你可能会得出”打日志就是浪费时间“的结论。其实我不是反对打日志,我是反对过度的打日志。
我们已经从 Stack Overflow移除所有的日志,除了依靠exception日志。老实说,我根本没有想念过它在这之后。
当谈到打日志,正确的答案不是”对,总是尽可能的多使用“。抵制给一切打日志的想法。简单和小范围使用,在大多数显而易见的严重的错误时用日志,确实需要时才使用。
【点评】:
作者Jeff Atwood是程序员大牛,Stack Overflow的创始人,认为日志很有吸引力,可以帮助定位问题,但问题和优点一样也很明显,过度的使用会产生很多问题:包括产生冗余的代码,性能的消耗。只有在必须要使用日志的重要场合才建议使用日志,反对过度的使用日志。
Tip
学习至少一个技术技巧
重装win10及Java开发环境
-
重装win10系统
- 重装系统之前,做好数据的备份,硬盘和云盘都可以,硬盘更快,因此我采用的硬盘
- PE U盘起系统,进入桌面(图1)用分区工具将机械盘HD0和固态盘HD1删除分区并格式化
- 开机后一直按ESC键进入BIOS,将HD1设置为优先启用,HD0优先级低
- PE U盘起系统,进入桌面点击安装系统(在这之前,先将240G的固态盘HD1分成2个区,125G为系统盘C,其余为普通盘D)
- 重装完成后,关机,拔掉U盘,开机自动,自动安装驱动
- 重启,正常进入win10
原来是win7+4G+机械硬盘,更换后是win10+8G DDR3+240G SSD,升级后跟新买的电脑样,运行十分流畅,赞极了。
-
jdk安装
- oracle官网下载jdk1.8
- 安装到本地磁盘,包括:jdk和jre
- 配置环境变量,同样包括jdk和jre
- 测试安装是否成功
-
IDEA安装
- 下载安装包,我的为2020.1版本
- 按提示安装即可
-
Maven
- 下载maven安装压缩包,解压到本地磁盘
- 配置环境变量,检查版本‘
- 新建本地仓库文件夹maven_repository
- 配置confsettings中本地仓库(
标签)、远程镜像源( 标签),将镜像配置为国内的镜像,会大大加快下载速度
-
Mysql
- 重装系统前,最重要的是将项目的数据库表导出为sql,参考Mysql 一次性备份导出/导入恢复所有数据库
- 特别注意版本,作者最初装的是latest version(8.0.22),安装后测试与原有的项目不兼容。更换为5.7.32 version工作正常
- 从官网下载安装压缩包,解压到本地磁盘D:mysql
- 根目录D:mysqlmysql-5.7.32-winx64下创建data文件夹和my.ini文件,配置my.ini文件
- 管理员身份运行cmd,执行几条指令进行安装和系统注册表注册,自行搜索安装教程。可参考mysql 8.0.22 安装配置图文教程
- 安装过程中,可能缺少一些文件和组件,根据报错信息关键字搜索解决即可
- 设置密码,参考mysql重置密码
- 导入sql恢复数据库表:
mysql>source f:sqlback.sql;
- 配置完成,正常使用数据库
-
其它软件安装
以下软件安装都比较简单,按提示操作很简单
- 文件管理软件:Total commander
- markdown编辑器:Typora
- 版本控制软件:Git
- IDE:vs Code
- 包管理:node.js V10.0.0
- web测试工具:postman
孔子说,工欲善其事,必先利其器。此刻,这句名言最能概括我此时的感受。原本我这段时间很忙,担心重装系统及配置环境会耽误太长的时间影响我目前的开发,犹豫了很久。现在看来电脑运行速度提升带来的开发效率提升了20倍以上,为自己的果断决策鼓掌。
Share
分享一篇有观点和思考的技术文章
从0开始学习 GitHub 系列之「团队合作利器 Branch」
米罗说
-
掌握时间管理是每个人的必修课
-
总有人比你NB,还比你更拼命-stormzhang