Algorithmjava
今天的算法题目是“存在重复元素”,从今天这道简单的算法题中,被折磨的死去活来的,不知道从何下手,只会最简单的遍历,结果是报了超时了。随后,本身思考了一阵,发现有官方题解,去里面寻找了一下解体思路,一会儿明朗起来。也发现了本身对于理论的不足!git
Review程序员
今日阅读文章:“Regex tutorial — A quick cheatsheet by examples”正则表达式
关于正则表达式的:算法
总结:从中又再次复习了正则表达式的一些内容,由于英文的缘故,后面的一些有点理解有点吃力,基础部分的语法获得了复习,从此要继续增强对正则表达式的练习。sql
Tipexpress
今天的tips就分享我本身写的经典快速排序吧(Java 8 默认的sort方法的排序性能已经很高了),按照其余人再加上本身的理解写出来的(性能仍是有待提高的),若是有错误,还请你们帮忙纠正,编程
基于Java编写的:后端
public static void quickSort(int[] arr, int left, int right) {
if (right - left > 0) {
int left1 = left;
int right1 = right;
int pivot = arr[left];
while(left1 <= right1) {
while (pivot > arr[left1]) {
++ left1;
}
while(pivot < arr[right1]) {
-- right1;
}
if (left1 <= right1) {
if (left1 == right1) {
arr[left] = arr[right1];
arr[right1] = pivot;
} else {
int temp = arr[right1];
arr[right1] = arr[left1];
arr[left1] = temp;
}
++ left1;
-- right1;
}
}
if (left < right1) {
quickSort(arr, left, right1);
}
if (left1 < right) {
quickSort(arr, left1, right);
}
}
}
复制代码
Shareapi
这是一篇关于快速排序的文章,由于今天的算法题,有考到关于排序的要点,因此本身就去检索了几篇关于快速排序的文章,这篇我认为是比较好的,也让我今天对快速排序有了更深的认识(我算法基础不好的)。但愿也能够帮助到其余人!
Algorithm 本周算法:136.只出现一次的数字 此次算法题由于受第一周算法的影响,以及它的题目描述中的“你能够不使用额外空间来实现吗?”,因而我就采用了排序加循环比较的方式。 个人题解思路:首先,先让数组进行排序,排序完后,进行循环比较,在每次循环开始前,我会设置一个值为false的Boolean标记,从索引0开始,将相邻的两个数同中间的一个数比较,若是相同将标记置为false,若是不一样将标记置为true。在单次循环的最后判断标记,若是为true,则为答案,若是为false则继续循环。在这里要注意两个临界值,首先是索引0的左边界值,及索引为length - 1的右边界值。
Review 本周阅读文章:“The Key To Accelerating Your Coding Skills” 这篇文章主要讲述了,在学习编程的过程当中,若是去快速的经过本身编程的拐点,经过这个拐点以后,自身的变成技能将会获得质的提高,可是在这个阶段时,会经历不少让你以为很艰难的事情,甚至让你想放弃,但只要坚持下来,就必定能够经过的。
Tip 受本周算法的影响,我发现了二进制数真的很神奇,我本身的题解耗时9ms,可是使用二进制的异或运算居然仅仅花费1ms。可是细想,这也合情合理,毕竟计算机自己就是二进制,这就是计算机最擅长的事情啊。 0异或任何数=任何数 1异或任何数-任何数取反 任何数异或本身=把本身置0
Share 启发很大,必须分享! The Key To Accelerating Your Coding Skills
Algorithm 本周LeetCode 题目:350. 两个数组的交集 II 题解思路:首先,将两个数组进行排序。比较两个数组的长度,将长度较小的那个放在外层循环,长度较长的放在内层循环,这样的作法是能够减小检索的次数,当数组长度相差极大的时候,这种方式的优势就能够凸显。随后,进行遍历获取交集,假设刚开始的前n次遍历没有找到相等的数字,则下次遍历还会从0索引开始。若是在前n次遍历中,在第n次遍历,找到相等项,处理以后结束内层循环,则第n+1次会在第n次的索引i+1 处的地方继续进行遍历,这样得益于排序以后的好处。 题解代码:
class Solution {
public int[] intersect(int[] nums1, int[] nums2) {
Arrays.sort(nums1);
Arrays.sort(nums2);
List<Integer> result = new ArrayList<>();
int start = 0;
if(nums1.length <= nums2.length) {
for (int i = 0; i < nums1.length; i++) {
int find = nums1[i];
for (int j = start; j < nums2.length; j++) {
if (find == nums2[j]) {
result.add(Integer.valueOf(find));
start = j + 1;
break;
}
}
}
} else {
for (int i = 0; i < nums2.length; i++) {
int find = nums2[i];
for (int j = start; j < nums1.length; j++) {
if (find == nums1[j]) {
result.add(Integer.valueOf(find));
start = j + 1;
break;
}
}
}
}
int[] nums3 = new int[result.size()];
for (int i = 0; i < result.size(); i++) {
nums3[i] = result.get(i);
}
return nums3;
}
}
复制代码
Review 本周文章:Why you should totally switch to Kotlin 我的看法;我本身的主语言是Java,这篇文章表达了许多有关于Kotlin这门编程语言的好处,的确有挺多解决Java语言以前的痛点的(我的基于JDK 8来阐述),好比两个对象的数据都相等的话,咱们在现实生活中就会认为这两个对象是相等的,而在Java的语法中,在默认的equals方法,由于这两个对象所存放的内存地址是不一样的,因此就会返回false,因此会让Java程序员重写了equals方法,可是在Kotlin中提供了==和===比较符,==只要数据相同就会返回true,而===的结果同默认的equals方法。这样省去了重复性的编码,可是Kotlin虽然是简化Java的代码风格,可是我的感受语法风格上仍是有些别扭,给个人感受是基于Java和Python中间,Python的语法是真的让我感受很简洁明了。
Tip 本周Tip:在Java中,方法的调用永远是值调用,而不像C++,Python有引用调用及值调用(基于JDK 8)
Share 最近迷上了一部美剧叫Stranger Things,中文译名:怪奇物语,很是好看。能够用来学习英语。
Algorithm 本周题目:66.加一 题解思路:本道题目总共分为两种常规状况,和一种临界状况。 1.常规状况一:数组末位值加一,不发生进位,直接将末位值加一,返回数组便可。这是最简单的状况 2.常规状况二:数组末位值加一,发生进位,从本道题目来说,发生进位的状况只有当前数组为9,当发生进位后,本位上的数值一定为0,进位后须要继续遍历该数组,移动当前索引减一,继续执行以上操做,如若继续发生进位,则继续如上操做,反之结束遍历,返回数组结果。 3.临界状况:此为常规状况二的临界状况,当数组元素全为9时,一定发生数组长度扩大一位,若是最后一次遍历时,发生进位状况,则出发此临界状况处理代码:数组长度扩大一位,首位填入1,其他用0填充,返回该构造数组。 题解代码:
class Solution {
public int[] plusOne(int[] digits) {
int begin = digits[digits.length - 1] + 1;
if (begin > 9) {
for (int i = digits.length - 1; i >= 0; i--) {
int flag = digits[i] + 1;
if (flag > 9) {
digits[i] = 0;
if (i == 0) {
int[] result = new int[digits.length + 1];
result[0] = 1;
for (int j = 1; j < digits.length; j++) {
result[j] = 0;
}
return result;
}
} else {
digits[i] = digits[i] + 1;
break;
}
}
} else {
digits[digits.length - 1] = digits[digits.length - 1] + 1;
}
return digits;
}
}
复制代码
Review lambda表达式基础入门 这是一篇关于Lambda的基础用法的简介,Lambda表达式是Java8的重大变化之一,它的到来让Java进入了函数式编程的领域,使用更简洁的代码,完成更多的功能,同时也增长代码的灵活性,让程序员从冗余的代码块中解放出来。在我查找Lambda表达式的文章的时候,我发现了一篇关于讲述Lambda表达式让代码变慢的说法,我我的不赞同这种说法,首先Lambda是Java以后发展的方向选择,及时在一些特殊的状况下,的确会变慢一些些,可是这也须要业务场景的加持,在可接受的范围内就是OK的。以后,学到了较为底层的时候,我就会去研究对应的场景,看是否变慢。
Tip Spring 的 AOP机制,是基于Java的代理机制,Spring用了更为强大的框架CGLIB。
Share lambda表达式基础入门 这是一篇介绍关于Lambda的基础用法
Algorithm 本周题目:283.移动零 解题思路:今天这道题目耗费了三个半小时还没解出来,由于一开始的思路错误了,致使一直在死胡同里面钻,以后要给本身解题设置时间限制,最多45分钟,若是没解出来就要去看别人的题解思路了。今天的这道题,我一直用二分查找的思想在想这道题,可是一直行不通,错了四次,而后我看了题解思路以后,豁然开朗,原来这道题的思路这么简单,我却花费了这么久还没解出来!!以后在解题的时候要多多转换思路,不能一直蒙着头一直往前冲。官方的题解思路是:这道题目能够分为两个子问题进行,1.不为0的数字移动至前面,2移动完成后在最后一位不为0的数字后的索引填充0。这样简单用几行代码就能够完成这道题目了。我用了数十行代码还没解决。 题解代码:
class Solution {
public void moveZeroes(int[] nums) {
int indexNotZero = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 0) {
nums[indexNotZero] = nums[i];
indexNotZero++;
}
}
for(int i = indexNotZero; i< nums.length; i++) {
nums[i] = 0;
}
}
}
复制代码
Review What I learned from doing 1000 code reviews 这篇文章告诉咱们如何在编码中改掉一些坏习惯
Tip 编码思路:经过拆解功能模块为若干个子问题,将关注点移至某子问题上,而不受其余子问题的困扰。我在这种开发模式上获益很大,在逐一解决子问题的过程当中,我发现我格外的轻松。考虑的方面仅仅只是子问题的部分,其余的子问题对我来讲是不可见的,我是根本不用去考虑,子问题封装的方法,我在另外一个子问题还能够复用,一箭双雕。跟我以前面对大问题去编码的状况有着质同样的变化。那时候我考虑这个考虑那个,最后把本身拧成了一团麻,不只耗费时间,并且问题还得不到完善的解决。因此在面对一个模块,或者一个功能的时候,必定要三思然后行,将模块的需求,及主要的状况,以及面对临界值的考虑思考清楚,头脑中有了成型的思路之后,编码的速度奇快无比,并且还很轻松,千万不能一股脑的就立马开始敲代码。
Share 修改tomcat端口方法 让服务器能够启动多个tomcat
Algorithm 本周算法题:1. 两数之和 题解思路:我在刚接触到这道题目的时候,又陷入了一种错误的思路中:把数组先进行排序... 这是多么错误的思路,出现这样的低级错误应该归根于个人算法基础薄弱,以及逻辑思惟不够发散,每每会局限于一种解法中。缺乏触类旁通的能力,从此仍是要多看书,写做,多多编写算法题以及进行思考。从各类不一样的方面去思考。回归正题,因而我花费了半个小时的时间,在错误的思路中解题,结果,意料之中的没有解决。在上周的作题经历中吸收的教训,我从新转换了思路。因而,发现了新的解题思路,但也是最最最普通的题解思路:双重循环遍历。细节在这里,我就不进行概述了,你们应该都明白。在二刷的时候,我会回来的!!! Review How to write a good software design doc 这篇文章讲诉如何去编写一篇软件设计文档,文章内容分为了四个部分: 1.为何要编写设计文档 2.设计文档中须要包含什么 3.怎么样去编写一篇设计文档 4.设计文档的整体流程是什么 一篇好的设计文档决定了一个项目的开头的好坏,若是在项目初期,对于项目的准备工做以及其相关的文档十分重视,那么这个项目在起点,就已经超过不少项目了,设计文档也是其中的一部分,它避免了开发人员去作一些错误的解决方案,大多数错误的解决方案在考虑设计项目架构的时候均可以被避免。然而一些公司不重视项目初期的构建 ,在项目后期,将会承受高返工率带来的巨大损失!制做软件产品也是一门手艺活,它须要开发团队去精雕细琢,而不是像快餐式的开发模式去对待,对本身开发产品付出的努力终将获得相对应的回报!
Tip 编码小贴士:信息隐藏。今天在《代码大全2》中阅读到这一部分,在这里简述个人思路:信息隐藏在程序设计中拥有相当重要的位置,它是做为面向对象设计原则的根基,例如,我如今所学习的Java语言中的一大特性——封装,就是这一原则的体现。信息隐藏能够下降类与类之间的耦合度,类把复杂的实现细节隐藏在类的内部,调用类无须知道其实现原理,当服务类修改内部的实现细节,其调用者将毫无察觉。信息隐藏能够将多变系统部分,固定在区域性的范围内,下降需求的变化对系统形成的影响。信息隐藏能够提升程序的伸缩性,将对应变化的部分隐藏至一个类或多个协做类中,如系统的硬件支持变化,只需更改对应类中的实现,实现改动量最小化,灵活性最大化!
Share 腾讯云入门中心 腾讯云入门中内心面有许多免费的教程,好比,如何搭建LAMP环境,Nginx环境等等,一些开发经常使用的环境。里面的教程相对于搜索引擎上我的编写的教程来讲,仍是比较清楚的。步骤详细,照着步骤去搭建,通常是不会出问题的。我我的以前搭建环境的时候,都是使用搜索引擎进行搜索,对各个搜索结果进行尝试,其中不乏有搭建失败,步骤模糊或者部署环境配置错误,所以花费了许多时间排错,这是很是惋惜的。因此,在这里分享一下我现阶段的思路:首先,登录对应的官网查找搭建文档,官网上都有对应的文档说明,可是诸如后端的主流开源框架,大部分都是英文的搭建文档,少部分提供中文(英文基础较差的同窗要加紧了,包括我本身),照着官网文档搭建百分之九十九都会成功的。其次,就是登录以上推荐的网站,查看是否有对应的教程。最后,若是以上两种都无论用的话,那就启动面向搜索引擎的模式吧!
Algorithm 本周算法:36.有效的数独 题解思路:首先这道题目我没有自行解决,第一次遇到中等难度的题目,就被围困半小时了结。因而我查阅了官方题解,它使用了27个HashMap做为存储集合,每行,每列,每一个框各有一个HashMap,对于我来讲比较有难度的地方为,它使用了一个转换公式将每一个框的索引肯定,该转换公式为:
int boxIndex = (i / 3) * 3 + j / 3;
复制代码
随后开始遍历整个二维char数组,使用Hash表的特性进行判断。
题解代码:
class Solution {
public boolean isValidSudoku(char[][] board) {
// init data
HashMap<Integer, Integer> [] rows = new HashMap[9];
HashMap<Integer, Integer>[] columns = new HashMap[9];
HashMap<Integer, Integer> [] boxes = new HashMap[9];
for (int i = 0; i < 9; i++) {
rows[i] = new HashMap<Integer, Integer>();
columns[i] = new HashMap<Integer, Integer>();
boxes[i] = new HashMap<Integer, Integer>();
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
int num = (int)board[i][j];
if (num != '.') {
int boxIndex = (i / 3) * 3 + j / 3;
rows[i].put(num, rows[i].getOrDefault(num, 0) + 1);
columns[j].put(num, columns[j].getOrDefault(num, 0) + 1);
boxes[boxIndex].put(num, boxes[boxIndex].getOrDefault(num, 0) + 1);
if (rows[i].get(num) > 1 || columns[j].get(num) > 1 || boxes[boxIndex].get(num) > 1) {
return false;
}
}
}
}
return true;
}
}
复制代码
Review The Decorator Pattern — A simple guide 这边文章主要是介绍装饰器模式的一些用法
Tip 这是我收集的Linux 命令行的用法 1.find usage Use find from the command line to locate a specific file by name or extension. The following example searches for .err files in the /home/username/ directory and all sub-directories: find /home/username/ -name ".err"
Share 分享一篇我本身编写的 elasticdump使用方法入门
Algorithm 本周算法:48.旋转图像(未解出) 题解思路:使用两次翻转来实现旋转效果,首先第一次翻转,将对应的行数字移动至它旋转后应在的数组中,可是位置并不必定正确,好比7原先在索引为2的数组,经过翻转将它移动至索引为0的数组中。第二次翻转则将每一个一维数组进行反转操做,将对应数字移动到正确的位置。
题解代码
class Solution {
public void rotate(int[][] matrix) {
int n = matrix.length;
for (int i = 0; i < n; i ++) {
for (int j = i; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
for (int i = 0; i < n; i ++) {
for (int j = 0; j < n / 2; j++) {
int tmp = matrix[i][j];
matrix[i][j] = matrix[i][n - j - 1];
matrix[i][n - j - 1] = tmp;
}
}
}
}
复制代码
Review 略
Tip 如下是关于cp命令的使用 cp usage \cp -rf file1.txt file2.txt cp前加上\ 在存在相同文件时,进行覆盖而不提示 -r -R Copy directories recursively. 递归复制文件及文件夹 -f If an existing destination file cannot be opened, remove it and try again. This option has no effect if the -n/--no-clobber option is used. However, it applies independently of -i/--interactive; neither option cancels the effect of the other,若是目标文件存在,强制将其删除,并从新执行复制操做。
Share 这是一篇关于FTP服务器安装的过程,我已根据这篇文章成功搭建出对应的FTP服务器。 ftp安装
Algorithm 344. 反转字符串 题解思路:采用二分法的思想,将整个数组一分为二,使用中间变量,由外向内的进行首位与末位的循环替换。 题解代码:
class Solution {
public void reverseString(char[] s) {
int length = s.length;
for (int i = 0; i < length / 2; i++) {
char temp = s[i];
s[i] = s[length - i - 1];
s[length - i - 1] = temp;
}
}
}
复制代码
Review
Callback Functions in JavaScript
这是关于JavaScript(如下简称为JS)回调函数的相关概念 1.JS中定义的函数能够传递代码块,随后在函数内部执行对应的函数 2.JS在函数体内部必定要判断做为回调函数参数的类型,由于JS是一种弱类型的语言,不像Java在定义参数的时候须要指定参数的类型,因此必定要作好参数检查的工做。 3.在函数体内部若是调用了异步函数,须要确认该异步函数与回调函数是否存在调用的顺序问题,若是存在,有一种解决方案:直接将回调函数放置异步函数的末尾。由于回调函数,极有可能在异步函数以前执行完毕。
Tip 在JS中应该避免使用var关键字变量,更改成let关键字定义变量,let 具备比var更为严格的语法要求,也是JS官方推荐使用。
Share 推荐MDN的JS学习指南,国庆后三天都在学习有关于JS方面的基础知识,准备学习好基础知识后去学习Vue.js框架,为正式入门的做业打下基础。
Algorithm 7.整数反转
题解代码
if (x == Integer.MAX_VALUE || x == Integer.MIN_VALUE) {
return 0;
}
StringBuilder stringBuilder = new StringBuilder(String.valueOf(Math.abs(x)));
long l = Long.parseLong(stringBuilder.reverse().toString());
if (l > Integer.MAX_VALUE) {
return 0;
}
if (x > 0) {
return (int)l;
} else {
return (int)l * -1;
}
复制代码
题解思路:
首先进行判断传入参数的大小是否等于整数范围的最大值或者最小值,如若如此,则直接进行返回0。接着将参数的绝对值进行字符化,反转以后转化为long类型整数,将此与Integer的最大值进行比较,若是大于则返回0。若是符合转换要求。对参数的正负性进行判断。为负数时乘以-1。 Review RESTful API Design - Step by Step Guide
这篇文章主要谈论关于Restful API的设计准则,我阅读完这篇文章后,我的受到了极大的启发,纠正了我在以前工做时对于Restful API设计的错误观念。
1.RESTful API的命名规则尽可能要简单而且能凸显提供的接口的功能性。在此以前,我对于API的命名主要以get为前缀开头,List为后缀结尾为主,伴随着中间一系列的动词及名词来代表此接口方法的功能性。这也是做者所提出的常见错误之一,好比关于产品方面的列表查询,我一般会使用productList,获取单一的产品,我会使用getProductById,虽然也能具体代表API的功能性,可是却带来了十分冗余的接口命名。而做者仅仅使用了products及products/id代表了我所须要接口的定义,却带来了及其简单的接口命名。
2.RESTful API须要版本控制。这一点再一次震撼到我,由于在我目前的工做生涯中,我历来都不知道RESTful API是须要进行版本控制的,个人一般作法是直接在当前版本上进行修改,若是变更过大,将致使调用者的代码报错,而且没有足够的时间去调整。
Tip Ubuntu 切换root用户不使用密码 sudo su - root
Share 今天分享的是Openstack的官方API文档,由于公司近期作的项目有设计虚拟化,因此本身也就在接触这方面的文档。可是Openstack的官方文档真的是很是的多。看完须要必定量的时间。本来想本身搭建一套Openstack的环境。结果被各类错误折磨的烦不胜烦,花费了7天时间。仍是没有搭建出来,最后不得已放弃了,由于本身的进度计划上还有更重要的事情要完成。
Algorithm 字符串中的第一个惟一字符
题解代码:
public int firstUniqChar(String s) {
HashMap<Character, Integer> count = new HashMap<Character, Integer>();
int n = s.length();
// build hash map : character and how often it appears
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
count.put(c, count.getOrDefault(c, 0) + 1);
}
// find the index
for (int i = 0; i < n; i++) {
if (count.get(s.charAt(i)) == 1)
return i;
}
return -1;
}
复制代码
题解思路:
根据题目就能够获得使用Hash表数据结构去解题,使用两个for循环,第一个for循环统计字符串中各个字符出现的次数,第二个for循环从新遍历整个字符串,若获得字符的次数为1,则这个字符为第一个惟一的字符,返回其index。若整个字符串都没有惟一,则返回-1.
Review 本周阅读OpenStack官方文档,OpenStack做为云计算时代的主力之一,着实让人佩服。从刚开始接触OpenStack时(也就在两周前),那时它对我来讲是蒙蒙胧胧的。在通过这两周的研究,发现网上的资料参次不齐,大多数都过期了。因此我就直接去啃官网的英文文档了,官方的文档十分完善,因此要接触或者学习OpenStack的同窗们,不要去百度找中文资料,直接上官网查阅英文资料。在通过“痛苦”的两周后,这周开始封装OpenStack的Keystone client以及glance client。
Tip 根据OpenStack glance rest api用来建立镜像,建立完后,只是一条记录,这条记录的状态显示排队中,须要另外上传镜像文件。
Share docs.openstack.org/train/
Algorithm
892.三维形体的表面积
题解思路:每一个正方形方格中叠放的正方体,底部和顶部两面一定暴露,不存在其余方格中遮挡状况,剩下东西南北四面,判断是否有正方体存在,若是有则减去对应的遮挡面积,反之加上全面积。以此遍历每一个方格,加上后则为总表面积。
题解代码:
class Solution {
public int surfaceArea(int[][] grid) {
// setting four direction
int[] dc = new int[] {0, 0, 1, -1};
int[] dt = new int[] {1, -1, 0, 0};
int N = grid.length;
int total = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int v = grid[i][j];
if (v > 0) {
total += 2;
for (int l = 0; l < 4; l++) {
int k = i + dc[l];
int h = j + dt[l];
int nv = 0;
if (0 <= k && k < N && 0 <= h && h < N) {
nv = grid[k][h];
}
total += Math.max(v - nv, 0);
}
}
}
}
return total;
}
}
复制代码
1114.按序打印
题解思路:采用Java关键字synchronized,用来控制线程打印的优先级,经过优先级高低依次获取锁,执行线程任务,随后再释放锁,唤醒等待线程。
题解代码:
class Foo {
public boolean firstFinished = false;
public boolean secondFinished = false;
public Object lock = new Object();
public Foo() {
}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
synchronized(lock) {
printFirst.run();
firstFinished = true;
lock.notifyAll();
}
}
public void second(Runnable printSecond) throws InterruptedException {
// printSecond.run() outputs "second". Do not change or remove this line.
synchronized(lock) {
while(!firstFinished) {
lock.wait();
}
printSecond.run();
secondFinished = true;
lock.notifyAll();
}
}
public void third(Runnable printThird) throws InterruptedException {
// printThird.run() outputs "third". Do not change or remove this line.
synchronized(lock) {
while(!secondFinished) {
lock.wait();
}
printThird.run();
}
}
}
复制代码
443.压缩字符串
思路:采用遍历,在遍历的过程当中比对字符的是否相等,而且统计相等字符的次数,这其中采用两种方式去处理相等字符及不相等状况。相等状况则sum加上1。不相等状况,sum若是大于1,则将sum转换为字符串,判断长度,遍历放入原数组中。最后处理最后一个字符串的临界值状况。
代码:
class Solution {
public int compress(char[] chars) {
int len = 0;
int sum = 0;
char original = chars[0];
int j = 0;
for (int i = 0; i < chars.length; i++) {
char cha = chars[i];
if (cha == original) {
sum += 1;
} else {
len += 1;
chars[j++] = chars[i - 1];
if (sum > 1) {
String numStr = String.valueOf(sum);
len += numStr.length();
for (int k = 0; k < numStr.length(); k++) {
chars[j++] = numStr.charAt(k);
}
}
original = cha;
sum = 1;
}
}
len += 1;
chars[j++] = chars[chars.length - 1];
if (sum > 1) {
String numStr = String.valueOf(sum);
len += numStr.length();
for (int k = 0; k < numStr.length(); k++) {
chars[j++] = numStr.charAt(k);
}
}
return len;
}
}
复制代码
53.最大子序和
思路:采用动态规划,遍历数组,若是sum大于0,则继续该次连续加法,若是sum 不大于0,则意味该次连续加法已不是最大和,重置连续加法,将sum至为当前的数字,每次加法操做,sum最后都须要与ans作比较。ans当前存放着连续的最大和,遍历结束后,ans里则为连续的最大和
代码:
class Solution {
public int maxSubArray(int[] nums) {
int ans = nums[0];
int sum = 0;
for (int num : nums) {
if (sum > 0) {
sum += num;
} else {
sum = num;
}
ans = Math.max(ans, sum);
}
return ans;
}
}
复制代码
206.反转链表
思路:采用遍历的方式,将链表的每一个节点的的下一个节点指向上一个节点,返回最后的引用
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while(curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
}
复制代码
Review
Elasticsearch user auth
根据ES官方文档,ES的Xpack鉴权框架在6.8以前是须要收费,我将ES版本从6.5更新至6.8,没有发生任何不兼容的问题。6.8后的Xpach免费提供了基础的鉴权服务,对于普通的使用者而言,已经足够使用。
Tip
Previous operation has not finished; run 'cleanup' if it was interrupted
执行 sqlite3 .svn/wc.db "delete from work_queue". 把队列清空。
执行 sqlite3 .svn/wc.db "select * from work_queue".\ 确认一下是否已经清空队列,发现已经没有记录显示,说明已经清空了。
最后尝试svn cleanup。
Share
SVN fail to cleanup
Algorithm
415.字符串相加
思路:采用遍历迭代,经过遍历两个字符串的各个字符位,将相对应的字符位进行相加操做,而且加上进位,处理相加和的价位,将剩下的值转换为字符串加入到StringBulider中,当遍历完成后,进行反转操做,便可获得最终的值。这里使用了一个小技巧,就是在代码num1.charAt(i) - '0'中,由于数字的字符减去0字符,便可获得它自己的整数值,根据ASCII表中的值来定义的。
代码:
class Solution {
public String addStrings(String num1, String num2) {
StringBuilder sb = new StringBuilder();
int i = num1.length() - 1;
int j = num2.length() - 1;
int carry = 0;
while(i >= 0 || j >= 0 ) {
int k = i >= 0 ? num1.charAt(i) - '0' : 0;
int h = j >= 0 ? num2.charAt(j) - '0' : 0;
int temp = k + h + carry;
carry = temp / 10;
sb.append(String.valueOf(temp % 10));
i--;
j--;
}
if(carry == 1) {
sb.append(carry);
}
return sb.reverse().toString();
}
}
复制代码