刷题主要是提升Java使用熟练度
01.两数相加
暴力算法用两个for循环很容易找出来,优化的一个方法就是使用哈希表进行优化,键值对中键是nums数组中某一个数,而值是其对应的nums索引,for循环遍历一次nums数组,如果哈希表存在键(target - nums[i]),那么就直接记录答案返回即可
上代码:
package 刷题库01;
import java.util.HashMap;
public class a01_两数之和 {
public int[] twoSum(int[] nums, int target) {
int[] ans = new int[2];
HashMap<Integer, Integer> hm = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (hm.containsKey(target - nums[i])) {
ans[0] = i;
ans[1] = hm.get(target - nums[i]);
}
hm.put(nums[i], i);
}
return ans;
}
}
02.两数相加
这道题是很典型的链表题目,我们可以自己新建链表,我们可以得知l1和l2两个链表相加得出来的新链表是可以通过每个节点对应相加得到的,因此我们可以声明新链表的头结点l3,同时声明移动结点pre,同时统计进位cent,如果cent为1就说明要进位,并且当l1和l2都为null,并且cent==0的时候才能结束
上代码
package 刷题库01;
public class a02_两数相加 {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode l3 = new ListNode();
ListNode pre = l3;
int cent = 0;
while (true) {
int a = 0, b = 0;
if (l1 != null) a = l1.val;
if (l2 != null) b = l2.val;
int num = a + b;
if (cent != 0) {
cent--;
num++;
}
if (num >= 10) {
cent++;
num -= 10;
}
pre.val = num;
if (l1 != null) l1 = l1.next; if (l2 != null) l2 = l2.next;
if (l1 == null && l2 == null && cent == 0) break;
pre.next = new ListNode();
pre = pre.next;
}
return l3;
}
}
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
03.无重复字符的最长子串
这道题可以用哈希表来进行重复判断,如果遇到重复的字符直接进行答案的更新,并且将循环体i更新为当前第一个重复字符的后一个位置,最后直接输出答案即可
上代码
package 刷题库01;
import java.util.HashMap;
public class a03_无重复的最长子串 {
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0) return 0;
int ans = 0;
HashMap <Character, Integer> hm = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
if (hm.get(s.charAt(i)) != null) {
ans = Math.max(ans, hm.size());
i = hm.get(s.charAt(i)) + 1;
hm.clear();
}
hm.put(s.charAt(i), i);
if (i == s.length() - 1) {
ans = Math.max(ans, hm.size());
}
}
return ans;
}
}
04.寻找两个正序数组的中位数
这道题可以直接对题目进行模拟,我们可以声明一个长度为n+m的新数组,然后分别将两个数组放进新数组中,利用Arrays中的静态方法sort进行排序,然后获取新数组的中位数索引,如果索引为奇数直接输出,如果为偶数就将前一个数也加上并平均再输出即可
上代码
package 刷题库01;
import java.util.Arrays;
public class a04_寻找两个数组的中位数 {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
double[] arr = new double[nums1.length + nums2.length];
int cent = 0;
for (int i = 0; i < nums1.length; i++) {
arr[cent++] = nums1[i];
}
for (int i = 0; i < nums2.length; i++) {
arr[cent++] = nums2[i];
}
Arrays.sort(arr);
if (cent % 2 != 0) {
int ans = (int)cent / 2;
return arr[ans];
}else {
int ans = (int)cent / 2;
return (arr[ans] + arr[ans - 1]) / 2.0;
}
}
}
05.最长回文子串
这道题的暴力做法就是用两个for循环加上StringBuilder进行判断,利用reverse进行翻转,如果原字符串等于翻转后的字符串,并且当前字符串长度大于当前记录的答案长度就进行更新,如果当前能获取到的最长子串长度还是小于ans的长度就提前结束即可
上代码
package 刷题库01;
public class a05_最长回文子串 {
public String longestPalindrome(String s) {
StringBuilder ans = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
for (int j = i + 1; j <= s.length(); j++) {
StringBuilder res = new StringBuilder(s.substring(i, j)).reverse();
StringBuilder res1 = new StringBuilder(s.substring(i, j));
if (res.toString().equals(res1.toString()) && res.length() > ans.length()) ans = new StringBuilder(res1);
if (s.length() - i <= ans.length()) return ans.toString();
}
}
return ans.toString();
}
}