<LC刷题一>相加为0的数之leetcode1&2&15&16

--题目导航见页面左上角的悬浮框#目录导航#--

相似题型导航 

1.1 twosum两数之和  ||  2.2 3Sum三数之和  ||  2.3 3Sum Closest最接近的三数之和

-------------------------------------------------------------------------------------------------------------------------------------

2.1 Add Two Numbers俩数相加 || 

一、简单

1.1 twosum两数之和

原题:

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。

实例:

给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

暴力解法(java):

复杂度分析:

  • 时间复杂度:O(n²), 对于每个元素,我们试图通过遍历数组的其余部分来寻找它所对应的目标元素,这将耗费 O(n)的时间。因此时间复杂度为 O(n²)

  • 空间复杂度:O(1)。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] index=new int[2];
        for(int i=0;i<nums.length;i++){
            for(int j=i+1;j<nums.length;j++){
             if(target==nums[i]+nums[j]){
                index[0]=i;
                index[1]=j;
                return index;
                                        }
                                    }
                                }
                return index;
        }
}

一遍hashmap法(java):

复杂度分析:

  • 时间复杂度:O(n), 我们只遍历了包含有 n 个元素的列表一次。在表中进行的每次查找只花费 O(1) 的时间。

  • 空间复杂度:O(n), 所需的额外空间取决于哈希表中存储的元素数量,该表最多需要存储 个元素。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int index[]=new int[2];
        HashMap <Integer,Integer> map=new HashMap<>(); //动态申请key,value均为Integer的名为map的HashMap函数类型
        for (int i=0;i<nums.length;i++){
            if(map.containsKey(target-nums[i])){   //判断map中是否存在key=target-num[i]
                index[0]=map.get(target-nums[i]);  //若存在则将key对应的value值赋给index
                index[1]=i;  
                return index;
            }else{
                map.put(nums[i],i);   //若不存在,则需要将i对应的数组值赋给map作为key,将i赋给map作为value,之所以反转的原因是前面是map.get(key)      
            }
        }
        return index;
    }
}

二、中等 

2.1 Add Two Numbers两数相加

原题:

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

实例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

 解决:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        int num=0;
        ListNode proNode=new ListNode(0); //定义链表头
        ListNode currentNode=new ListNode(0);  //定义链表节点接受俩数之和
        proNode.next=currentNode; //连接俩个链表节点
        do{
            int sum=(l1!=null?l1.val:0)+(l2!=null?l2.val:0)+num; //当俩个链表都不为null时节点与进位相加
            num=sum/10;  //取进位
            int result=sum%10;   //取余数
            currentNode.val=result;  //将结果填入新链表的节点中
            l1=l1!=null?l1.next:l1;  //移动参与计算的链表头
            l2=l2!=null?l2.next:l2;  //移动参与计算的链表头
            if(l1!=null||l2!=null||num!=0){  //判断俩链表是否为null,之所以使用l1!=null||l2!null而不是&&的原因是:
// 当测试集为[1,8] [0]时,使用&&判断俩链表均不为空会导致长短不同的链表报错,导致结果为[1] currentNode.next
=new ListNode(0); currentNode=currentNode.next; //连接俩节点 } }while(l1!=null||l2!=null||num!=0); return proNode.next; 返回链表 } }

proNode.next=currentNode 单向节点链接

2.2 3Sum三数之和

 原题:

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

实例:

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

解决:

在2Sum的问题上解决3Sum的问题,选定i=0,i++来依次作为target,k=i+1,k++和j=nums.length-1 ,j-- 在[Ak~Aj]之间判断是否有nums[k]+nums[j]=-nums[i]的集合

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result=new LinkedList<>();
        if(nums!=null&&nums.length>2){
            Arrays.sort(nums);
            for(int i=0;i<nums.length-2; ){
                int j=i+1;
                int k= nums.length-1;
                while(j<k){
                    if (nums[j]+nums[k]==-nums[i]) {
                        List<Integer> list = new ArrayList<>(3);
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(nums[k]);
                        result.add(list);

                        k--;
                        j++; //下面while中继续进行-- ++的目的是为了去重
                        while (k > j && nums[k] == nums[k + 1]) {
                            k--;
                        }
                        while (k > j && nums[j] == nums[j - 1]) {
                            j++;
                        }
                    }

                    else if (nums[j]+nums[k]<-nums[i]){
                        j++;
                        while (k>j&&nums[j]==nums[j-1]){
                            j++;
                        }
                    }
                    else{
                        k--;
                        while (k>j&&nums[k]==nums[k+1]){
                            k--;
                        }
                    }
                }
                i++;
                while(i<nums.length-2&&nums[i]==nums[i-1]){
                    i++;
                }
            }
        }
        return result;
    }
} 

2.3 3Sum Closest最接近的三数之和

原题:

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

实例:

例如,给定数组 nums = [-121,-4], 和 target = 1.

与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

解决:

与三数之和的解题思路差不多

class Solution {
    public int threeSumClosest(int[] nums ,int target){
        Arrays.sort(nums);
        long minDiff=Long.MAX_VALUE;
        int result=0;
        int diff=0;
        int sum=0;
        for (int i=0;i<nums.length-2;i++){
            int j=i+1;
            int k=nums.length-1;
            while (j<k){
                sum=nums[i]+nums[j]+nums[k];
                diff=Math.abs(sum-target);
                if (diff==0){
                    return sum;
                }if (diff<minDiff){
                    minDiff=diff;
                    result=sum;
                }if (sum>target){
                    k--;
                }else {
                    j++;
                }

            }

        }
        return result;
    }

}

  Math.abs(sum-target)表示取sum-target的绝对值。

【持续更新中,欢迎交流讨论】

原文地址:https://www.cnblogs.com/huxinga/p/9787129.html