1. 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那两整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
链接:两数之和
(1)两重循环,暴力求解
class Solution {
public int[] twoSum(int[] nums, int target) {
for(int i = 0; i < nums.length; i++) {
for(int j = i+1; j < nums.length; j++) {
if(target == nums[i] + nums[j]) {
return new int[]{i, j};
}
}
}
return new int[0];
}
}
(2)使用HashMap
解题思路: 遍历数组,查看map中是否存在另一个值与其相加等于target,如果存在则直接返回这两个数值的下标,否则将该值放到map中。
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[]{map.get(target - nums[i]), i};
}else {
map.put(nums[i], i);
}
}
throw new IllegalArgumentException();
}
}
2. 两数相加
给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字0之外,这两个数都不会以0开头。
链接:两数相加
/**
* 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 = null, tail = null;
int sum = 0, carry = 0;
while(l1 != null || l2 != null) {
int x = (l1 != null) ? l1.val : 0;
int y = (l2 != null) ? l2.val : 0;
sum = carry + x + y;
carry = sum / 10;
if(head == null) {
head = new ListNode(sum % 10);
tail = head;
}else {
tail.next = new ListNode(sum % 10);
tail = tail.next;
}
if(l1 != null) l1 = l1.next;
if(l2 != null) l2 = l2.next;
}
if(carry > 0) {
tail.next = new ListNode(carry);
}
return head;
}
}
3. 无重复字符的最长子串
给定一个字符串s ,请你找出其中不含有重复字符的最长子串的长度。
链接:无重复字符的最长子串
class Solution {
public int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet<>();
int start = 0, end = 0;
int ans = 0;
while(start < s.length() && end < s.length()) {
if(set.contains(s.charAt(end))) {
set.remove(s.charAt(start));
start ++;
}else {
ans = Math.max(ans, end-start+1);
set.add(s.charAt(end));
end ++;
}
}
return ans;
}
}
49.字母异位词分组(2024.05.29)
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
链接:字母异位词分组
使用HashMap,将每个单词根据字母进行排序并将其作为Map的key
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<>();
for (String str : strs) {
char[] chr = str.toCharArray();
Arrays.sort(chr);
String str1 = new String(chr);
if (map.containsKey(str1)) {
List<String> list = map.get(str1);
list.add(str);
} else {
List<String> list = new ArrayList<>();
list.add(str);
map.put(str1, list);
}
}
return new ArrayList<List<String>>(map.values());
}
}
70. 爬楼梯
假设你正在爬楼梯。需要n阶你才能到达楼顶。
每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?
链接:爬楼梯
class Solution {
public int climbStairs(int n) {
int[] nums = new int[n+1];
nums[1] = 1;
if(n<2) return 1;
else {
nums[2] = 2;
for(int i = 3; i <= n; i++) {
nums[i] = nums[i-1] + nums[i-2];
}
return nums[n];
}
}
}
94. 二叉树的中序遍历
给定一个二叉树的根节点root,返回它的中序遍历 。
链接:二叉树的中序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
inorder(list, root);
return list;
}
public void inorder(ArrayList<Integer> list, TreeNode root) {
if(root == null) {
return ;
}else {
inorder(list, root.left);
list.add(root.val);
inorder(list, root.right);
}
}
}
128. 最长连续序列(2024.05.30)
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
链接:最长连续序列
将数组放进HashSet中去重,每次去查num+i
是否在数组中存在,最后的i+1
即为该连续序列的长度。重点:为避免重复查询,利用num-1
,若num-1
不存在,则说明num是序列的第一个值,否则不是可直接跳过。
class Solution {
public int longestConsecutive(int[] nums) {
int longestConsecutive = 0;
Set<Integer> set = new HashSet<>();
for(int num : nums) {
set.add(num);
}
for(int i = 0; i < nums.length; i++) {
if(!set.contains(nums[i]-1)) {
int longest = 1;
while(set.contains(nums[i] + longest)) { //开头
longest ++;
}
longestConsecutive = longestConsecutive > longest ? longestConsecutive: longest;
}
}
return longestConsecutive;
}
}
283. 移动零(2024.05.31)
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
链接:移动零
每次将不为0的值移到前面,循环结束时前面的值将保持原有的相对顺序,而0则排到最后。即设置i、j两个指针,当i!=0
时,交换i和j的值,并将j+1。
class Solution {
public void moveZeroes(int[] nums) {
int j = 0;
for(int i = 0; i < nums.length; i++) {
if(nums[i] != 0) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
j++;
}
}
}
}