1.两数之和

题目描述:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

2 -> 4->3;

5->6->4;

返回结果:

7-> 0->8;

示例:

1
2
3
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
* 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 prev = new ListNode(0);
//定义一个进位数的指针,用来存储当两数之和大于10的时候,
int carry = 0;
//定义一个可移动的指针,用来指向存储两个数之和的位置
ListNode cur = prev;
//当l1 不等于null或l2 不等于空时,就进入循环
while(l1!=null || l2!=null){
//如果l1 不等于null时,就取他的值,等于null时,就赋值0,保持两个链表具有相同的位数
int x= l1 !=null ? l1.val : 0;
//如果l1 不等于null时,就取他的值,等于null时,就赋值0,保持两个链表具有相同的位数
int y = l2 !=null ? l2.val : 0;
//将两个链表的值,进行相加,并加上进位数
int sum = x + y + carry;
//计算进位数
carry = sum / 10;
//计算两个数的和,此时排除超过10的请况(大于10,取余数)
sum = sum % 10;
//将求和数赋值给新链表的节点,
//注意这个时候不能直接将sum赋值给cur.next = sum。这时候会报,类型不匹配。
//所以这个时候要创一个新的节点,将值赋予节点
cur.next = new ListNode(sum);
//将新链表的节点后移
cur = cur.next;
//当链表l1不等于null的时候,将l1 的节点后移
if(l1 !=null){
l1 = l1.next;
}
//当链表l2 不等于null的时候,将l2的节点后移
if(l2 !=null){
l2 = l2.next;
}
}
//如果最后两个数,相加的时候有进位数的时候,就将进位数,赋予链表的新节点。
//两数相加最多小于20,所以的的值最大只能时1
if(carry == 1){
cur.next = new ListNode(carry);
}
//返回链表的头节点
return prev.next;
}
}

2.给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:

输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:

输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

题解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public int lengthOfLongestSubstring04(String s) {
// 单个字符作为key,字符在字符串中的下标作为value
Map<Character, Integer> map = new HashMap<>();
// 最大值
int maxLen = 0;
// 左边界
int left = 0;
// 这个循环的一些想法,之前老喜欢把字符串转字符数组,然后用数组去操作,其实直接遍历索引也是可以的
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
/**
* 要理解下面的代码首先要想明白获得最长字串的逻辑
* 这里一共存在两个变量:
* - left:表示字串最左边字符的索引位置
* - i:遍历的每个字符索引位置,我们全靠这个字符来完成这道题,i这个变量存在三种情况需要考虑
* 1) s.charAt(i)在[left, i)之间不存在重复字符
* - 就把s.charAt(i)放到map中,最长长度同时也加一
* 2) s.charAt(i)在[left, i)之间存在重复字符
* - 获得[left, i)范围内重复字符的下标h,让left = h + 1,此时新的字串开始匹配,新的长度变成了i - left + 1 = 1
* - 更新map中重复字符的索引位置为i
* 3) s.charAt(i)在[0, left)之间存在重复字符
* - 我们在发现重复字符后都要更新该字符在map中的索引位置,就是为了避免之前的重复元素对当前判断造成影响
* - 但是譬如acbba这样一个字符:当遍历到第二个b时,可知h = map.get('b'),所以h=2,那么newLeft=h+1=3;
* 之后遍历到字符a,h = map.get('a'),发现此时h=0,newLeft=h+1=1;这种情况明显不合理,所以要求left=Math.max(left, newLeft)
* - 更新map中重复字符的索引位置为i,最长长度同时也加一
*
*/
if (map.containsKey(c)) {
left = Math.max(left, map.get(c) + 1);
}
map.put(c, i);
maxLen = Math.max(maxLen, i - left + 1);
}
return maxLen;
}

3,寻找两个正序数组的中位数

题目描述:

给定两个大小分别为 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int lenth1=nums1.length;
int lenth2 = nums2.length;
int[] nums3 = new int[lenth1+lenth2];
int i=0 ,j=0, k=0;
while(i<lenth1 && j<lenth2){ //相当于双指针移动算法
if(nums1[i]<=nums2[j]){ //两个数组谁值小谁赋值
nums3[k++]=nums1[i++];
}else{
nums3[k++]=nums2[j++];
}
}
while(i<lenth1) //将剩下的没赋值的给依次赋值
nums3[k++]=nums1[i++];
while(j<lenth2)
nums3[k++]= nums2[j++];
if((lenth1+lenth2)%2==1){
return nums3[(lenth1+lenth2)/2]; //奇数直接返回
}else{
double z= nums3[(lenth1+lenth2)/2]+nums3[(lenth1+lenth2)/2-1];//偶数个数相加除二返回
return z/2;
}

}
}

5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例 1:

输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:

输入:s = “cbbd”
输出:“bb”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public String longestPalindrome(String s) {
String ans = "";
for(int i=0;i<s.length();i++){
int l = i-1;
int r = i + 1;
while(l >= 0 && r< s.length() && s.charAt(l)==s.charAt(r)){
l--;
r++;
}
if(ans.length()< r- l -1)
ans = s.substring(l+1,r);
l = i;
r = i + 1;
while(l>=0 && r<s.length() && s.charAt(l)==s.charAt(r)){
l--;
r++;
}
if(ans.length()<r-l-1)
ans = s.substring(l+1,r);
}
return ans;
}
}