最近被中期答辩弄得昏头转向,本来想着和计算机打交道,计算机会听话,会遵循指令做事,没想到研究的人工智能,甚至要把人类智能加入到计算机中,当然没有说不好,可是我们研究的有点偏,本来以为是高级的算法、数据结构等,没想到最后研究的还是人,真叫人头秃。
上个周末,挤出一些时间学习了一下Elasticsearch,参考的是b站的狂神课程,课程的笔记在个人的博客学习笔记传送门
项目使用springboot继承ES模仿京东的搜索页面,源码地址:项目源码
由于学校学业的一些困扰,好久没有刷题,本次都为简单题目。
1.股票问题
问题
给定一个数组,数组的元素表示第i天股票的价格,只允许购买一笔交易,求能够获取的最大收益
输入:[7,1,5,3,6,4]
输出:5 第2天买入第5天卖出 6-1 = 5
卖出必须在买入之后。
问题分析
买卖股票当然是在最低点买入,在最高点卖出这样才能够使得收益最大化。使用两个指针,一个指向买入的位置一个指向卖出的位置,循环遍历时,遇到小于买入时的元素,就将买入位置修改,否则修改卖出的位置,计算最大收益。
代码
class Solution {
public int maxProfit(int[] prices) {
//记录收益值,买入的位置、卖出的位置
int count = 0;
int buy = 0;
int sell = -1;
//遍历数组,获取最大收益
for(int i=1;i<prices.length;i++){
if(prices[i]<prices[buy])buy = i;
else{
sell = i;
int temp = prices[sell] - prices[buy];
count = count>temp?count:temp;
}
}
//如果一直是递减的股市,那么就不买入,收益为0
if(sell == -1)return 0;
else return count;
}
}
问题二
还是股票的问题,这一次可以多次买卖
输入:[7,1,5,3,6,4]
收益: 7
第二天买入,第三天卖出收益4,第四天买入,第五天卖出收益为3,总收益为7
问题分析
对于可以多次进行买卖时,在股票下跌之前抛出,下跌后买入,每次都能够获取一定的收益。
代码
class Solution {
public int maxProfit(int[] prices) {
//定义总收益、买入日期、当前的位置
int count = 0;
int buy = 0;
int i=1;
//只要股市有下跌,就抛出,获取收益,如果一直减小,就在小的那一天买入
for(;i<prices.length;i++){
if(prices[i]<prices[i-1]){
count+=(prices[i-1] - prices[buy]);
buy = i;
}
}
//将最后的全部抛出,获取最后的收益,返回
if(prices[i-1]>prices[buy]) count += prices[i-1] - prices[buy];
return count;
}
}
简单总结一下,好好学习,不做韭菜。
2.回文验证
给定一个字符串,验证该字符串是否为回文串,只考虑数组和字母,字母不区分大小写。
输入:“A man, a plan, a canal: Panama”
输出: true
问题分析
个人使用双指针来进行比对,对于字母元素的比对,ASCII表中大写字母+32为小写的字母,因此没有使用toLowCase这样的转换函数。
代码
class Solution {
public boolean isPalindrome(String s) {
int left= 0;
int right = s.length()-1;
//双指针,左右两边各指向一个字符进行判断其是否相等
while(left<right){
char ch1 = s.charAt(left);
char ch2 = s.charAt(right);
//左边不为数字或者字符,左指针右移
while(left<right&&!isChar(ch1)&&!isNum(ch1)){
left++;
ch1 = s.charAt(left);
}
while(left<right&&!isChar(ch2)&&!isNum(ch2)){
right--;
ch2 = s.charAt(right);
}
//这个边界是因为P以后的字符和数字相差32,干扰后面的字符判断,例如'0'+32 == 'P' 这个结果为true,因此需要排除
if (((isChar(ch1) && isNum(ch2)) || (isChar(ch2) && isNum(ch1)) || (isNum(ch1) && isNum(ch2)))&& (ch1 != ch2))
return false;
if(ch1!=ch2&&ch1!=ch2+32&&ch1!=ch2-32)return false;
else {left++;right--;}
}
return true;
}
//判断字符为字母
public boolean isChar(char ch){
return (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') );
}
//判断字符为数字
public boolean isNum(char ch){
return ('0' <= ch && ch <= '9');
}
}
3.旋转数组最小值
旋转数组是将数组最开始的若干个元素搬运到数组的末尾,称之为旋转。本题目输入是一个递增数组的旋转数组,输出是数组中最小的元素。
输入:[3,4,5,1,2] 输出:1
输入:[2,2,2,0,1] 输出:0
问题分析
代码
自己做的题目很少有双百的现象,这个估计过于简单,大神们不屑于做。
class Solution {
public int minArray(int[] numbers) {
//从后向前依次比较,遇到大的数停止,返回;否则最小的是第一个位置的元素
for(int i=numbers.length-1;i>0;i--){
if(numbers[i-1]>numbers[i])return numbers[i];
}
return numbers[0];
}
}