力扣算法JAVA刷题笔记【一】 两数之和,两数相加,无重复字符的最长子串,寻找两个正序数组的中位数,最长回文子串,正则表达式匹配,盛最多水的容器,三数之和,电话号码字母组合,删除链表的倒数第N个结点

本专栏内容为:力扣算法热题100的JAVA刷题笔记
开发环境: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.

java新手请看这篇:java 的链表实现

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;//返回结果链表头结点
    }

}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值