1. 两数之和
题目描述:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例一:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
Java实现
方法一:暴力枚举,对每一个x,遍历寻找target-x的下标
- 时间复杂度O(N²)
- 空间复杂度O(1)
方法二:利用HashMap,对于每一个x,我们首先查询哈希表中是否存在target-x,如果不存在则将x插入哈希表,如果存在则可以直接返回x的当前下标和target-x的下标。
import java.util.HashMap;
//方法二
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if(map.containsKey(target-nums[i])){
return new int[]{i,map.get(target-nums[i])};
}else map.put(nums[i],i);//存入时值在前,下标在后,方便获得下标
}
return new int[0];
}
}
2. 两数相加
题目描述:
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例一:
输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[7,0,8] 解释:342 + 465 = 807.
Java实现:
方法一:从头结点开始一个节点一个节点对应相加,注意进位,详细见注释
/**
* 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 head = new ListNode(); //新建头部节点
ListNode tail = head; //用于添加和后移
int c = 0;//进位
// 循环条件为其中一个链表不为空或者进位位不为0
while(l1!=null || l2!=null || c != 0){
int l1Val = l1 != null ? l1.val : 0; //结点为空时默认值为0
int l2Val = l2 != null ? l2.val : 0;
int t = l1Val + l2Val + c;
ListNode temp = new ListNode(t%10);
c = t/10;
tail.next = temp; //tail的后面接上temp
tail = temp; //tail后移一位
// 如果不进行判断会报错
if(l1 != null) l1 = l1.next;
if(l2 != null) l2 = l2.next;
}
//由于第一个temp是赋值给tail.next,head没有被赋值
//所以返回从head.next开始的链表
return head.next;
}
}
3. 无重复字符的最长子串
题目描述
给定一个字符串 s
,请你找出其中不含有重复字符的 最长子串 的长度。
示例一:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是"abc",所以其长度为 3。
Java实现:
方法一:滑动窗口
class Solution {
public int lengthOfLongestSubstring(String s) {
char[] chars = s.toCharArray(); //先将字符串转化为字符数组
HashSet<Character> set = new HashSet<>(); //用一个set来记录重复字符
int max=0; //记录最大值
int k=0;//相对于第一个字符的偏移量
for(int i=0;i<chars.length;i++){
if(i!=0){
set.remove(chars[i-1]);//滑动窗口,滑一个字符就把最前面的字符删掉
}
//遇到重复字符或 k偏移到最后一个字符时跳出循环
while ( k< chars.length && !set.contains(chars[k])){
set.add(chars[k]);
k++;
}
// 主要以set的长度来表示无重复字符子串的长度
// 取当前set长度和之前的最大值之间的最大值,更新最大值
max = Math.max(set.size(),max);
}
return max;
}
}
5. 最长回文子串
题目描述:
给你一个字符串 s
,找到 s
中最长的回文子串。
示例一:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
Java实现:
方法一:动态规划
方法二:从长到短截取遍历所有子串,写一个函数判断是不是回文;主要这个判断不要用reserve函数,时间通过不了。
方法三:中心扩展
/*
* 方法三
*/
class Solution{
public String longestPalindrome(String s) {
//边界条件判断
if (s.length() < 2)
return s;
//start表示最长回文串开始的位置,
//maxLen表示最长回文串的长度
int start = 0, maxLen = 0;
int length = s.length();
for (int i = 0; i < length; ) {
//如果剩余子串长度小于目前查找到的最长回文子串的长度,直接终止循环
// (因为即使他是回文子串,也不是最长的,所以直接终止循环,不再判断)
if (length - i <= maxLen / 2)
break;
int left = i, right = i;
while (right < length - 1 && s.charAt(right + 1) == s.charAt(right))
++right; //过滤掉重复的
//下次在判断的时候从重复的下一个字符开始判断
i = right + 1;
//然后往两边判断,找出回文子串的长度
while (right < length - 1 && left > 0 && s.charAt(right + 1) == s.charAt(left - 1)) {
++right;
--left;
}
//保留最长的
if (right - left + 1 > maxLen) {
start = left;
maxLen = right - left + 1;
}
}
//截取回文子串
return s.substring(start, start + maxLen);
}
}