前言
以下内容的标题格式为“PXXX.XXX”,PXXX表示题目序号,大家可以自行前往力扣官网查看,题号后面的就是题目
本笔记旨在记录更加便利的算法设计,优化结构安排,同时汲取大佬们的顶级思想,提供巧妙的解题步骤
P1.两数之和
别暴力!!!用时很大
假设目前有数组[2,7,8],求target=9
- 我们根据题目要求得知num[i]+num[j]=target,把他进一步变形为target-num[i]=num[j]
- 为避免双重遍历我们导入一个key和value都是integar类型的映射
- 映射中存储的key为数值,而value存储的是下标,因为我们需要对数值之差进行比对才可以得出结果,故我们比对的是key
- 每次遍历都检测是否存在target-num[i]的数,如果没有将把当前值塞入映射里面
- 当我们遍历到第二个元素,即num[2]==7时,此时target-num[2]=9-7=2,因为我们映射中已经存储了数组的第一个元素num[1]==2,此时我们containsKey就可以找到该映射元素和当前元素相匹配,然后我们再输出数值和下标即可
我们对哈希表查找的是key,所以需要直接把数字作为key才可以查找得到
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; ++i) {
if (hashtable.containsKey(target - nums[i])) {
return new int[]{hashtable.get(target - nums[i]), i};
}
hashtable.put(nums[i], i);
}
return new int[0];
}
P14.最长公共前缀
我们直接使用分治算法求解,下面解析分治算法的主要实现原理
- 将给定字符串数组从中间切开分成两部分(不用在意数组元素奇数个还是偶数个),然后对左右两边的数组分别执行取相同字符串前缀的操作
- 因为我们使用了递归,那么函数会一直切分直到最小单位(数组左右各一个字符串),然后对该最小单位执行commonPrefix
- 最小单位找到了相同前缀后反馈给上一级,上一级又重复执行此过程,自底向上直到最顶层比较完毕
commonPrefix函数用到的思想是:直接选取两字符串中较小的那一个的长度作为循环次数,然后使用chatAt方法逐个对俩字符串头部相同前缀进行比对;全部比对一致就直接返回短的字符串,若中间比对中断就从中断位置的上一个位置返回subString
// 分治处理连续字符串问题
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) {
return ""; // 判断字符串不存在或者长度为0时直接返回空字符串
} else {
return longestCommonPrefix(strs, 0, strs.length - 1);
}
}
// 分治算法主体
public String longestCommonPrefix(String[] strs, int start, int end) {
if (start == end) return strs[start];
else {
// 分治主体,不断分割自己,直到最小单位后执行取前缀操作,然后自底向上不断迭代
int mid = (end - start) / 2 + start;
String lcpLeft = longestCommonPrefix(strs, start, mid);
String lcpRight = longestCommonPrefix(strs, mid + 1, end);
return commonPrefix(lcpLeft, lcpRight);
}
}
// 取字符串相同前缀方法
public String commonPrefix(String lcpLeft, String lcpRight) {
int minLenght = Math.min(lcpLeft.length(), lcpRight.length());
for (int i = 0; i < minLenght; i++) {
if (lcpLeft.charAt(i) != lcpRight.charAt(i)) {
return lcpLeft.substring(0, i);
}
}
return lcpLeft.substring(0, minLenght);
}
TE.对称结构处理专题
力扣 P1614括号最大深度 | 简单
题目:https://leetcode-cn.com/problems/maximum-nesting-depth-of-the-parentheses/
通过题设不难发现,我们只有 一种类型的对称结构 需要判断,也就是"(“和”)",此时我们就不需要使用复杂的栈!我们可以仅通过一个变量数值的增减实现类似栈的效果
以下代码实现的功能
- maxD记录当前深度,nowMax记录最大深度
- 一次遍历字符串中的每个字符,判断是否为"(“或”)"
- 一旦遇见左括号,不用想直接maxD++,深度加一即可
- 但遇见了右括号,就需要maxD–,视为一次类似出栈的操作(因为上次遇见"("时+1,此刻的-1含义不言而喻)
- 但需要注意,maxD–前,还需要判断目前的最大深度和已经存储好的上次的最大深度比较,取较大值!
public int maxDepth(String s) {
int maxD=0,nowMax=0;
for(Character c:s.toCharArray()){
if(c=='(') maxD++;
else if(c==')'){
nowMax=Math.max(nowMax,maxD);
maxD--;
}
}
return nowMax;
}