力扣第一题两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
只会存在一个有效答案
进阶:你可以想出一个时间复杂度小于 O(n2) 的算法吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
利用数据结构HashMap的containsKey方法和get方法的时间复杂度都是O(1)的特性,将target - nums[i]存入HashMap的key里,将i存入map的value里 每次循环判断key是否存在,且当前key对应的value是否等于i(有可能会有3,3这种样例,所以必须要判断一下)key存在且value不等于i那么就可以将value和i分别存入result里返回result。
public class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
int[] result = new int[2];
for (int i = 0;i < nums.length;i++) {
if(map.containsKey(nums[i]) && map.get(nums[i]) != i){
result[0] = map.get(nums[i]);
result[1] = i;
return result;
}map.put(target - nums[i],i);
}
return result;
}
}
力扣第二题两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
提示:
每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这题主要考察的链表这个数据结构的知识点,和大数加法思想
注意事项:题目上给了链表的类,但是Java里手扣需要注意的是要先new好对象再去连接指针,否则会出现空指针异常。
大数处理要考虑进位问题。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode result = new ListNode();
ListNode headNode1 = l1;
ListNode headNode2 = l2;
ListNode head = result;
int up = 0;
while (headNode1 != null || headNode2 != null){
if (headNode1 == null){
int temp = up + headNode2.val;
ListNode headNode3 = new ListNode(temp % 10);
up = temp / 10;
head.next = headNode3;
head = head.next;
headNode2 = headNode2.next;
}else if(headNode2 == null){
int temp = up + headNode1.val;
ListNode headNode3 = new ListNode(temp % 10);
up = temp / 10;
head.next = headNode3;
head = head.next;
headNode1 = headNode1.next;
}else{
int temp = up + headNode1.val + headNode2.val;
ListNode headNode3 = new ListNode(temp % 10);
up = temp / 10;
head.next = headNode3;
head = head.next;
headNode1 = headNode1.next;
headNode2 = headNode2.next;
}
if(up != 0){
ListNode headNode3 = new ListNode(up);
}
}
return result.next;
}
}
力扣第三题无重复字符的最长字串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题可以用滑动窗口的思想
用两个指针当作左窗口和又窗口,遍历整个字符串寻找出最大的字串的长度,返回result
class Solution {
public int lengthOfLongestSubstring(String s) {
int result = 0,j = 0;
HashMap<Character, Integer> map = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
Integer temp = map.put(s.charAt(i),i+1);
if(temp != null){
j = Math.max(j,temp);
}
result = Math.max(result,i - j + 1);
}
return result;
}
}
力扣第四题寻找两个正序数组的中位数
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
暴破…
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
提示:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
int[] a = new int[n+m];
for (int i = 0; i < m; i++) {
a[i] = nums1[i];
}
for (int i = 0; i < n; i++) {
a[i+m] = nums2[i];
}
Arrays.sort(a);
if((m+n) % 2 == 0){
return (a[(m+n) /2] + a[(m+n) / 2 - 1]) / 2.0;
}else{
return a[(m+n-1)/2];
}
}
}
力扣第五题最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
经典的马拉车算法(专门用来做回文子串的算法)(个人理解):
想理解马拉车算法呢,首先要先理解一下中间扩散法,
中间探取法:
①.遍历字符串
②.判断arr[i - 1]和arr[i +1 ]是否为空,再判断他们是否相等,接着向两边扩散判断,直到找出最大的子串为止。
但是这么做只能对形如“aba"这种的有用形如”aa“这种是不行的。
要判断形如”aa“这种只能再加个判断i和i +1 i -1 是否相同 然后再去更改扩散的条件
那么有没有什么办法能让我们不考虑那么多呢?当然就是我们的马拉车算法了
假如我们的字符串是这样
在这里插入图片描述
我们将每个字符中间都添加一对‘#’变成这样
这时我们现在只需要考虑① ②就行了。最后的结果只用考虑奇数下标的就行了
以上仅是个人理解,如果有大佬有更其他见解,欢迎评论区留言。
代码如下:
class Solution {
public String longestPalindrome(String s) {
StringBuilder sb = new StringBuilder();
sb.append("#");
for (int i = 0; i < s.length(); i++) {
sb.append(s.charAt(i));
sb.append("#");
}
int[] a = new int[sb.length()];
int max = 0,k = 0;
for (int i = 0; i < sb.length(); i++) {
int j = 1,temp = 1;
while (i-j >= 0 && i+j < sb.length()){//这里保证了指针i前后都不会为空
if(sb.charAt(i-j) != sb.charAt(i+j)){
break;
}
a[i] = temp * 2 - 1;
temp++;
j++;
}
if(max < a[i]){
max = a[i];
k = i;
}
}
String result = "";
for(int i = k - max/2; i <= k + (max/2);i += 2){
if(i % 2 != 0){
result += sb.charAt(i) +"";
}
}
return result;
}
}