if (nums[i] + nums[j] == target) {
//如果满足条件,获取第二个索引
index2 = j;
//设置i的值,用于结束外层循环
i = nums.length;
break;
}
}
}
//新数组赋值
nums1[0] = index1;
nums1[1] = index2;
//返回数组
return nums1;
}
官方解答
//官方给的最优解,时间复杂度:O(N)
public static int[] twoSum1(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];
}
总结
自己写的代码能够成功运行,但是相对于效率而言,官方的解答时间复杂度更低,执行效率更高。原本以为能够做出来就行了,才发现差别还是蛮大的,一个效率高的算法真的是太考究了,立志今后解题尽量将效率达到极致!
双倍快乐
====
力扣第三题
题目描述:无重复字符的最长子串(中等)
给定一个字符串
s
,请你找出其中不含有重复字符的最长子串的长度。
示例:
输入:s = “abcabcbb”
输出:3
解释:因为无重复字符的最长子串是 “abc”,所以其长度为 3。
输入:s = “bbbbb”
输出:1
解释:因为无重复字符的最长子串是 “b”,所以其长度为 1。
输入:s = “pwwkew”
输出:3
解释:因为无重复字符的最长子串是 “wke”,所以其长度为 3。
输入:s = “”
输出:0
解题思路
刚开始是想用数组存放字符,然后循环进行比较,判断字符是否存在,最后返回最长的子串,然后发现难以实现,有一个问题解决起来太过于麻烦。。然后就果断换一种方式,想起来使用去重的集合,定义一个HashSet集合,该集合可以自动去重,用于循环将字符依次存放到该集合,再用循环进行判断集合中是否有该字符 (此处的判断是写在另一个方法内的,这里调用该方法进行判断),然后再记录集合的长度,重置集合,最后获取最大的长度并返回。
代码实现
//自己做的最优解,时间复杂度:O(N^2)
//用时:一个小时。。
public static int lengthOfLongestSubstring2(String s) {
//计长度
int k = 1;
//最大的长度
int max = 0;
//设置Set集合
HashSet<Character> hashSet = new HashSet<Character>();
//判断字符串是否为空
if (s.length() != 0) {
//循环字符串
for (int i = 0; i < s.length(); i++) {
//赋值给集合
hashSet.add(s.charAt(i));
//循环字符的后一位
for (int j = i + 1; j < s.length(); j++) {
//判断集合中是否存在字符
if (!ifTrue(hashSet, s.charAt(j))) {
//不存在就添加到集合
hashSet.add(s.charAt(j));
} else break;
//记录集合长度
k = hashSet.size();
}
//集合重置
hashSet.clear();
//判断并赋值
if (k > max) {
max = k;
}
}
}
return max;
}
//判断集合中是否有字符c
public static boolean ifTrue(HashSet<Character> hashSet, char c) {
boolean b = false;
for (Character s : hashSet) {
if (s == c) {
return true;
}
}
return b;
}
波仔的解答
//波仔的解答,时间复杂度:O(N)
public static int lengthOfLongestSubstring1(String s) {
int n = s.length(), ans = 0;
//定义一个hash表,字符串和长度
Map<Character, Integer> map = new HashMap<>();
for (int end = 0, start = 0; end < n; end++) {
//获取单个字符
char alpha = s.charAt(end);
//如果查找到有数据
if (map.containsKey(alpha)) {
//更新start
start = Math.max(map.get(alpha), start);
}
//不管存进来没更新一下ans,就是我们得结果
//end-start+1就是我们统计出来字符串得长度
ans = Math.max(ans, end - start + 1);
//存入数据,有重复得在上面已经查找过了,所以一定能找出来
map.put(s.charAt(end), end + 1);
}
return ans;
}
评论区大哥解答
//评论区大哥的解答,时间复杂度:O(N)
public static int lengthOfLongestSubstring(String s) {
//记录字符上一次出现的位置
int[] last = new int[128];
for (int i = 0; i < 128; i++) {
last[i] = -1;
}
int n = s.length();
int res = 0;
int start = 0; //窗口开始位置
for (int i = 0; i < n; i++) {
//获取当前字符的ASCII码
int index = s.charAt(i); //a --97
//获取字符出现的最大下标值
start = Math.max(start, last[index] + 1);
//获取最大长度的子串
res = Math.max(res, i - start + 1);
//下标值存放到数组
last[index] = i;
}
return res;
}
总结
刚开始的解题思路不对,绕了很久也花了很多时间也没做出来,后面用集合才勉强做出来,先把思路确定好了再行动,写代码的效率应该会高些。后面看了小波波和评论区大哥的解答,才发现是我肤浅了,是我没想到的方法,逻辑性比较强,下次再遇到这种类型的题,我必定将它拿捏!
三倍快乐
====
力扣第四题
题目描述:寻找两个正序数的中位数(困难)
给定两个大小分别为
m
和n
的正序 (从小到大)数组nums1
和nums2
。请你找出并返回这两个正序数组的中位数。
示例:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3],中位数 2。
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
输入:nums1 = [], nums2 = [1]
输出:1.00000
解题思路
刚看到这题目就有一个疑问,这么简单的题咋会定义为困难哦,也没管那么多,先实现了再说,想到的就是把两个数组合并到一个新数组,然后用arrays中的sort方法排序,最后判断数组的长度,算出中位数并返回。
代码实现
//自己所写的最优解,时间复杂度:O(N)
//用时:十五分钟
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
//定义变量
double num = 0;
//创建一个新数组,用于存放给出的两个数组值
int[] nums3 = new int[nums1.length + nums2.length];
//循环将第一个数组值赋值给新数组
for (int i = 0; i < nums1.length; i++) {
nums3[i] = nums1[i];
}
//循环将第二个数组继续赋值给新数组
for (int i = 0, j = nums1.length; i < nums2.length; i++, j++) {
nums3[j] = nums2[i];
}
//使用Arrays的方法排序
Arrays.sort(nums3);
//判断数组长度是奇数还是偶数
if (nums3.length % 2 != 0) {
//奇数,直接取出中位数
num = nums3[nums3.length / 2];
} else {
//偶数,取出中间那个下标的值,再加上它前面那个值,除以二就是中位数
num = nums3[nums3.length / 2] + nums3[nums3.length / 2 - 1];
num /= 2;
}
return num;
}
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
自己摸索成长,自己不成体系的自学效果低效漫长且无助。**
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-JuaPYbkK-1715797084227)]
[外链图片转存中…(img-45fRQ3Yd-1715797084228)]
[外链图片转存中…(img-5xxNzAr3-1715797084228)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!