1.两数之和
注意: map.put(nums[i],i); 放的位置很重要,注释位置会出现错误,
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++){
// map.put(nums[i],i);
int complement = target-nums[i];
if(map.containsKey(complement)&& map.get(complement) != i){
return new int[] { map.get(complement), i };
}
map.put(nums[i],i);
}
throw new RuntimeException("没有正确的返回值");
}
2.两数相加
注意:常犯的错误: (1)int x= p1==null?0:p1.val; //经常写成p1.val==null
(2)head需要new ListNode(0); //需要new 一个值进去。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode p1= l1;
ListNode p2=l2;
int root=0;
ListNode head=new ListNode(0);
ListNode cur=head;
while(p1!=null||p2!=null){
int x= p1==null?0:p1.val;
int y=p2==null?0:p2.val;
int sum =x+y;
cur.next= new ListNode((sum+root)%10);
root =(sum+root)/10;
if(p1!=null) p1=p1.next;
if(p2!=null) p2=p2.next;
cur =cur.next;
}
if(root>0){
cur.next =new ListNode(root);
}
return head.next;
}
}
3. 无重复字符的最长子串
和LeetCode1044,区分开
(1)集合是不能存放基本类型的数据的,
(2)在取子字符串的时候应该是前闭后开.理解三个for循环后面的等号,取不取。暴力法:
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int ans = 0;
for (int i = 0; i < n; i++)
for (int j = i + 1; j <= n; j++)
if (allUnique(s, i, j)) ans = Math.max(ans, j - i);
return ans;
}
public boolean allUnique(String s, int start, int end) {
Set<Character> set = new HashSet<>();
for (int i = start; i < end; i++) {
Character ch = s.charAt(i);
if (set.contains(ch)) return false;
set.add(ch);
}
return true;
}
}
注意:set,的add和remove方法里面放的是具体的元素。
public int lengthOfLongestSubstring(String s) {
int n=s.length();
Set<Character> set =new HashSet<Character>();
int i=0;
int j=0;
int res =0;
while(i<n&&j<n){
if(!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
res =Math.max(res,j-i);
}else{
set.remove(s.charAt(i++));
}
}
return res;
}
5.最长回文子串
动态规划解法
// 使用动态规划法
public String longestPalindrome_reconstructure3(String s) { // 第三次对代码进行重构
if (s.length() < 2) { // 单个字符肯定是回文串,直接返回s
return s;
}
boolean[][] dp = new boolean[s.length()][s.length()]; // 初始化一个二维数组,值默认是false
String result = s.substring(0,1);
for (int j = 0; j < s.length(); j++){
for (int i = 0; i <= j; i++){
//小于3是因为aba一定是回文
dp[i][j] = s.charAt(i) == s.charAt(j) &&(j - i < 3 || dp[i+1][j-1]);
if (dp[i][j]){
if (j - i + 1 > result.length()){
result = s.substring(i, j + 1);
}
}
}
}
return result;
}
中心扩展法:
下面是根据长度求出,开始和结束位置的一个示意图
public String longestPalindrome(String s) {
if (s == null || s.length() < 1) return "";
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
//最长回文子串是奇数的情况
int len1 = expandAroundCenter(s, i, i);
//最长回文子串是偶数的情况
int len2 = expandAroundCenter(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > end - start) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
return s.substring(start, end + 1);
}
private int expandAroundCenter(String s, int left, int right) {
int L = left, R = right;
while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {
L--;
R++;
}
//这里是-1而不是+1,是因为上面在进行条件判断之后不满足,还是执行了一次逻辑操作的。
return R - L - 1;
}
7.整数反转
class Solution {
public int reverse(int x) {
int rev =0;
int pop;
while(x!=0){
pop = x%10;
x/=10;
//因为int类型的范围是 -2^31——2^31-1,即-2147483648——2147483647
if(rev>Integer.MAX_VALUE/10||(rev==Integer.MAX_VALUE/10&&pop>7)) return 0;
if(rev<Integer.MIN_VALUE/10||(rev==Integer.MIN_VALUE/10&&pop<-8))
return 0;
rev = rev*10+pop;
}
return rev;
}
}
8.字符串转换成整数
class Solution {
public int myAtoi(String str) {
//清空字符串开头和末尾空格(这是trim方法功能,事实上我们只需清空开头空格)
str = str.trim();
//java正则表达式
Pattern p = Pattern.compile("^[\\+\\-]?\\d+");
Matcher m = p.matcher(str);
int value = 0;
//判断是否能匹配
if (m.find()){
//字符串转整数,溢出
try {
value = Integer.parseInt(str.substring(m.start(), m.end()));
} catch (Exception e){
//由于有的字符串"42"没有正号,所以我们判断'-'
value = str.charAt(0) == '-' ? Integer.MIN_VALUE: Integer.MAX_VALUE;
}
}
return value;
}
}
9.回文数
class Solution {
public boolean isPalindrome(int x) {
if(x<0) return false;
int rev =0;
int num =x;
while(num!=0){
rev =rev*10+num%10;
num/=10;
}
return rev==x;
}
}