开发环境:java 16.0.1
开发IDE:IDEA
一、两数之和(num: 1)
1.1 题目描述
给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应到一个答案里,但是,数组中同一个元素在答案里不能重复出现,可以按照任意顺序返回答案。
示例1
输入:nums = [2,7,11,15] target = 9
输出:[0,1]
因为 nums[0] + nums[1] == 9 ,返回 [0, 1]
示例2
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例3
输入:nums = [3,3], target = 6
输出:[0,1]
提示
只会存在一个有效答案
进阶
你可以想出一个时间复杂度小于O(n2)的算法吗?
1.2 解题方法一:双重循环暴力破解 O(n2)
在力扣上运行的时候是不需要主函数代码的,但是自己在IDEA中编写时为了测试方便需要有主函数,因此这部分的笔记会附带上主函数的代码,自己测试时运行主类的main方法即可
双重循环暴力破解没什么好说的,揪住当前的数值,在数组中循环看有没有相加等于目标值的就可以了。
主函数(用于测试,测试时从键盘键入输入内容)
import java.util.*;
public class main {
public static void main(String[] args) {
//设置输入值
int[] nums = new int[2];
int[] res = new int[2];
int target ;
//键盘输入数组
System.out.println("Please input nums: ");
Scanner sc = new Scanner(System.in);
for (int i = 0; i < nums.length; i++) {
nums[i] = sc.nextInt();
}
//键盘输入target
System.out.println("Please input target: ");
target = sc.nextInt();
//声明一个该类的对象
sumOftwo1 sum = new sumOftwo1();
//调用该类
res = sum.twoSum(nums,target);
for (int q = 0; q < res.length; q++) {
System.out.println(res[q]);
}
}
}
功能函数
public class sumOftwo1 {
public int[] twoSum(int[] nums, int target) {
//num.length 数组的长度 nums.length.for快捷键遍历
int[] res = new int[2];
for (int i = 0; i < nums.length; i++) {
for (int j = i+1; j < nums.length; j++) {
if(nums[i]+nums[j]==target)
{
res[0] = i;
res[1] = j;
break;
}
}
}
return res;
}
}
1.3 解题方法二:使用哈希表 O(n)
这种提升速度方式的思路是:空间换时间
哈希表本质上是一种映射对照,把数组的值和下表存进去,然后哈希查找。
import java.util.HashMap;
public class sumOftwoHash {
public int[] twoSum(int[] nums, int target){
//建立一个哈希表
HashMap<Integer,Integer> map = new HashMap<>();
//向哈希表中加入映射
for (int i = 0; i < nums.length; i++) {
map.put(nums[i],i);
}
for (int j = 0; j < nums.length; j++) {
int x = nums[j];
//使用哈希表查找
if (map.containsKey(target - x)) {
int index = map.get(target); //获得映射的另一边
if (j != index) return new int[]{j, index}; //这个if条件是因为题干要求不能返回两个相同下标
}
}
return new int[0];//为了不报错放着的,没什么意义
}
}
二、两数相加 (num:2)
2.1 题目描述
给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,而且每个节点只能存储一位数字。
请你将两个数相加,并以相同的形式返回一个和的链表。
你可以假设除了数字0之外,这两个数都不会以0开头。
提示
每个链表中的结点数在范围(1,100)内
题目数据保证数字前面不含有前导0
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
2.1 解决方法
用于测试的主函数(结构体单独存成一个Class文件)
import java.util.*;
public class main {
public static void main(String[] args) {
/*设置输入的两个链表
class ListNode {
//Definition for singly-linked list. 链表结点结构体的定义
int val; //结点值
ListNode next; //结点指针
ListNode() {} //构造函数?
ListNode(int val) { this.val = val; } //函数:设定当前结点值
ListNode(int val, ListNode next) { this.val = val; this.next = next; } //函数:关联下个结点
}*/
//键盘输入两个链表的值
int len = 3;//为了测试给定的输入长度,测试时每次要手动改一下
System.out.println("Please input l1: ");
int[] num1 = new int[len];
Scanner sc = new Scanner(System.in);
for (int i = 0; i < len; i++) {
num1[i] = sc.nextInt();
}
//输入链表2的值
System.out.println("Please input l2: ");
int[] num2 = new int[len];
for (int i = 0; i < len; i++) {
num2[i] = sc.nextInt();
}
//创建链表1(尾插法)——L1是这条指针的头结点
ListNode p = null;
ListNode l1 = p;
for (int j : num1) {
ListNode q = new ListNode(j);
//首次插入判断
if (l1 == null) {
l1 = p = q;
}
p.next = q;
p = p.next;
}
//创建链表2(尾插法)——L2是这条指针的头结点
ListNode p1 = null;
ListNode l2 = p1;
for (int j : num2) {
ListNode q1 = new ListNode(j);
//首次插入判断
if (l2 == null) {
l2 = p1 = q1;
}
p1.next = q1;
p1 = p1.next;
}
//输出两个链表(遍历链表)
ListNode p3 = new ListNode();
p3 = l1;
while(p3 != null)
{
System.out.println(p3.val);
p3 = p3.next;
}
p3 = l2;
while(p3 != null)
{
System.out.println(p3.val);
p3= p3.next;
}
//声明一个该类的对象
sumChain2 sum = new sumChain2();
ListNode res = new ListNode();
res = sum.addTwoNumbers(l1,l2);
p3 = res;
while(p3 != null)
{
System.out.println(p3.val);
p3= p3.next;
}
}
}
执行代码(没搞完,明天接着做,累了(sumChain2.class))
import java.util.ArrayList;
import java.math.*;
public class sumChain2 {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//遍历两个链表,获得两个数字
ListNode p = new ListNode();
p=l1;
int x = 0;
double sum1 = 0;
while(p!=null)
{
sum1 = sum1 + p.val * Math.pow(10,x);
x = x+1;
p = p.next;
}
double sum2 = 0;
x = 0;
p = l2;
while(p!=null)
{
sum2 = sum2 + p.val * Math.pow(10,x);
x = x+1;
p = p.next;
}
//sum是加和之后的数
int sum = (int)sum1 + (int)sum2;
//建立结果链表:尾插法
ListNode p1 = null;
ListNode head = p1;
//特殊处理:结果为0时
if(sum == 0)
{
ListNode head0 = new ListNode(0);
head0.next = null;
return head0;
}
while(sum!=0){
ListNode q = new ListNode(sum % 10);
if(head == null)
{
head = p1 = q;
}
p1.next = q;
p1 = p1.next;
sum = sum / 10;
}
return head;//返回结果链表头结点
}
}