1. 两数之和
1. 题目
1. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.代码
2.1 暴力法
2.2 (优解)利用map做哈希表
import java.util.HashMap;
import java.util.Map;
class Solution1 {
public static void main(String[] args) {
Solution1 solution = new Solution1();
int[] result = solution.twoSum(new int[] {3, 2, 4}, 6);
for (int i = 0; i < result.length; i++) {
System.out.println(result[i]);
}
}
/**
* 暴力法
* @param nums
* @param target
* @return
*/
public int[] twoSum1(int[] nums, int target) {
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[i] + nums[j] == target) {
return new int[]{i, j};
}
}
}
throw new IllegalArgumentException("No two sum solution");
}
/**
* (优解)利用map做哈希表
* @param nums
* @param target
* @return
*/
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < nums.length; i++) {
int needNumber = target - nums[i];
if (map.containsKey(needNumber)) {
return new int[]{map.get(needNumber), i};
} else {
map.put(nums[i], i);
}
}
throw new IllegalArgumentException("No two sum solution");
}
}
4. 算法用时
语言 | 方法 | 执行用时 | 内存消耗 |
---|---|---|---|
Java | 暴力法 | 5 ms | 36.8 MB |
Java | 利用map做哈希表 | 23 ms | 37.9 MB |
5. 感想
两种方法在性能方面差很多,所以解题时多用数据结构有利于提升性能。
2. 两数相加
1. 题目
2. 两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.代码
2.1 处理各种情景 将结果集放入l1中
2.2 (优解)官方解答(有修改)
import leet.code.entity.ListNode;
/*
2. 两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution2 {
public static void main(String[] args) {
Solution2 solution = new Solution2();
int[] l1Arr = new int[] {2, 4, 3};
int[] l2Arr = new int[] {5, 6, 4};
ListNode l1 = solution.creatLink(l1Arr);
ListNode l2 = solution.creatLink(l2Arr);
solution.addTwoNumbers(l1, l2);
}
private ListNode creatLink(int[] l1Arr) {
if (l1Arr == null || l1Arr.length == 0) {
return null;
}
ListNode head = null;
ListNode pre = null;
for (int i = 0; i < l1Arr.length; i++) {
ListNode tem = new ListNode(l1Arr[i]);
if (i == 0) {
head = tem;
} else {
pre.next = tem;
}
pre = tem;
}
return head;
}
/**
* 处理各种情景 将结果集放入l1中
* @param l1
* @param l2
* @return
*/
public ListNode addTwoNumbers1(ListNode l1, ListNode l2) {
boolean carry = false;
ListNode l1pre = null;
ListNode result = l1;
while (l1 != null || l2 != null || carry) {
// l1 + l2
int sum;
if (l1 != null && l2 != null) {
sum = l1.val + l2.val;
} else if (l1 == null) {
l1 = new ListNode(0);
if (l1pre != null) {
l1pre.next = l1;
}
if (l2 != null) {
sum = l1.val + l2.val;
} else {
sum = 0;
}
} else {
//l1 != null && l2 == null
sum = l1.val;
}
// 处理上一次进位
if (carry) {
sum++;
carry = false;
}
// 处理当前进位
if (sum > 9) {
sum -= 10;
carry = true;
}
//赋值
l1.val = sum;
l1pre = l1;
if (l1 != null) l1 = l1.next;
if (l2 != null) l2 = l2.next;
}
return result;
}
/**
* 官方解答(有修改) 优解
* @param l1
* @param l2
* @return
*/
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
ListNode curr = dummyHead;
int carry = 0;
while (l1 != null || l2 != null) {
int x = (l1 != null) ? l1.val : 0;
int y = (l2 != null) ? l2.val : 0;
int sum = carry + x + y;
carry = sum / 10;
curr.next = new ListNode(sum % 10);
curr = curr.next;
if (l1 != null) l1 = l1.next;
if (l2 != null) l2 = l2.next;
}
if (carry > 0) {
curr.next = new ListNode(carry);
}
return dummyHead.next;
}
}
4. 算法用时
/
| 语言 | 方法 | 执行用时 | 内存消耗 |
| --- | --- | --- | --- |
| Java | 处理各种情景 | 2 ms | 44.2 MB |
| Java | 官方解答 | 2 ms | 44.7 MB |
/
5. 感想
两种算法相差无几,就是思考方式不同,一种是将所有可能都罗列出来,另一种是综合考虑。