2020.12.5

题目

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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解答

方法一: 枚举(暴力求解)

时间复杂度:O(N^2)
空间复杂度:O(1)

//java
class Solution{
    public int[] towSum(int[] nums, int target){
    //创建一个数组 来存放数据
    	int[] a = new int[2];
        int n = nums.length;
        for(int i=0;i<n;++i){
            for(int j =i+1;j<n;++j){
                if(nums[i] +nums[j] == target){
                	a[0] = i;
                	a[1] = j;
                    return new a;
                }
            }
        }
        return new int[0];
    }
}
class Solution:
    def twoSum(self,nums):
        n = len(nums)
        for i in range(n):
            for j in range(i+1,n):
                if nums[i] + nums[j] == target:
                    return [i,j]
        return []
方法二: 哈希表

15 三数之和

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

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

示例:

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解答

方法一:暴力求解
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Set result = new HashSet();
        for(int i =0; i < nums.length; i++) {
            for (int j = i +1; j< nums.length; j++) {
                for(int l = j +1; l < nums.length; l++) {
                    if (nums[i] + nums[j]+nums[l] == 0) {
                        List result2 = new ArrayList();
                        result2.add(nums[i]);
                        result2.add(nums[j]);
                        result2.add(nums[l]);
                         Collections.sort(result2);
                        result.add(result2);
                    }
                }
            }
        }
        return new ArrayList<>(result);
    }
}
方法二:排序 + 双指针(排序后夹逼)

时间复杂度 O(N^2)
空间复杂度 O(1)

class Solution {
    public static List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ans = new ArrayList();
        int len = nums.length;
        if(nums == null || len < 3) return ans;
        Arrays.sort(nums); // 排序
        for (int i = 0; i < len ; i++) {
            if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
            if(i > 0 && nums[i] == nums[i-1]) continue; // 去重
            int L = i+1;
            int R = len-1;
            while(L < R){
                int sum = nums[i] + nums[L] + nums[R];
                if(sum == 0){
                    ans.add(Arrays.asList(nums[i],nums[L],nums[R]));
                    while (L<R && nums[L] == nums[L+1]) L++; // 去重
                    while (L<R && nums[R] == nums[R-1]) R--; // 去重
                    L++;
                    R--;
                }
                else if (sum < 0) L++;
                else if (sum > 0) R--;
            }
        }        
        return ans;
    }
}


class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # 去除例外
        n = len(nums)
        res = []
        if (not nums or n < 3):
            return []

        # 排序
        nums.sort()
        # 创建一个列表用来保存数据
        res = []
        # 遍历排序后的数组
        for i in range(n):
            # 若 nums[i]>0nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 00,直接返回结果。
            if (nums[i] > 0):
                return res
            # 对于重复元素:跳过,避免出现重复解
            if (i > 0 and nums[i] == nums[i - 1]):
                continue
            # 令左指针 L=i+1L=i+1,右指针 R=n-1R=n−1,当 L<RL<R 时,执行循环
            L = i + 1
            R = n - 1
            while (L < R):
                # 找到结果,就输入列表中
                if (nums[i] + nums[L] + nums[R] == 0):
                    res.append([nums[i], nums[L], nums[R]])
                    while (L < R and nums[L] == nums[L + 1]):
                        L = L + 1
                    while (L < R and nums[R] == nums[R - 1]):
                        R = R - 1
                    L = L + 1
                    R = R - 1
                # 若和大于 0,说明nums[R] 太大,R 左移
                elif (nums[i] + nums[L] + nums[R] > 0):
                    R = R - 1
                # 若和小于 0,说明 nums[L] 太小,L 右移
                else:
                    L = L + 1
        return res

复习:
java集合
  • Java 集合框架主要包括两种类型的容器: 一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。
  • Collection 又有 3 种子类型,List、Set 和 Queue
    在这里插入图片描述

遍历 ArrayList

import java.util.*;
 
public class Test{
 public static void main(String[] args) {
     List<String> list=new ArrayList<String>();
     list.add("Hello");
     list.add("World");
     list.add("HAHAHAHA");
     //第一种遍历方法使用 For-Each 遍历 List
     for (String str : list) {            //也可以改写 for(int i=0;i<list.size();i++) 这种形式
        System.out.println(str);
     }
 
     //第二种遍历,把链表变为数组相关的内容进行遍历
     String[] strArray=new String[list.size()];
     list.toArray(strArray);
     for(int i=0;i<strArray.length;i++) //这里也可以改写为  for(String str:strArray) 这种形式
     {
        System.out.println(strArray[i]);
     }
     
    //第三种遍历 使用迭代器进行相关遍历
     
     Iterator<String> ite=list.iterator();
     while(ite.hasNext())//判断下一个元素之后有值
     {
         System.out.println(ite.next());
     }
 }
}

遍历 Map

import java.util.*;
 
public class Test{
     public static void main(String[] args) {
      Map<String, String> map = new HashMap<String, String>();
      map.put("1", "value1");
      map.put("2", "value2");
      map.put("3", "value3");
      
      //第一种:普遍使用,二次取值
      System.out.println("通过Map.keySet遍历key和value:");
      for (String key : map.keySet()) {
       System.out.println("key= "+ key + " and value= " + map.get(key));
      }
      
      //第二种
      System.out.println("通过Map.entrySet使用iterator遍历key和value:");
      Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
      while (it.hasNext()) {
       Map.Entry<String, String> entry = it.next();
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
      }
      
      //第三种:推荐,尤其是容量大时
      System.out.println("通过Map.entrySet遍历key和value");
      for (Map.Entry<String, String> entry : map.entrySet()) {
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
      }
    
      //第四种
      System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
      for (String v : map.values()) {
       System.out.println("value= " + v);
      }
     }
}
Java Iterator(迭代器)

Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法

迭代器 it 的两个基本操作是 next 、hasNext 和 remove。
调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
调用 it.hasNext() 用于检测集合中是否还有元素。
调用 it.remove() 将迭代器返回的元素删除。

package com.company;


import java.util.ArrayList;
import java.util.Iterator;

public class Main {

    public static void main(String[] args) {

        // 创建集合
        ArrayList<String> sites = new ArrayList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Zhihu");

        // 获取迭代器
        Iterator<String> it = sites.iterator();

        // 输出集合中的第一个元素
        System.out.println(it.next());

        // 输出集合中的所有元素
        //让迭代器 it 逐个返回集合中所有元素最简单的方法是使用 while 循环:
        while (it.hasNext()) {
            System.out.println(it.next());

        }
    }
}



Java ArrayList

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。

以下情况使用 ArrayList :
频繁访问列表中的某一个元素。
只需要在列表末尾进行添加和删除元素操作。

package com.company;

import java.util.ArrayList;
import java.util.Collections;

public class Main {

    public static void main(String[] args) {
    	//实例化对象
        ArrayList<String> sites = new ArrayList<String>();
        //增
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Runoob");
        sites.add("Weibo");
        sites.add("Google");
        System.out.println(sites);
        //访问
        System.out.println(sites.get(1));
        //修改
        sites.set(1, "Wiki"); // 第一个参数为索引位置,第二个为要修改的值
        System.out.println(sites);
        //删除
        sites.remove(1); // 删除第四个元素
        System.out.println(sites);
        //计算大小
        System.out.println(sites.size());
        //排序 (按字母大小)
        Collections.sort(sites);  // 字母排序
        for (String i : sites) {
            System.out.println(i);
        }
    }
}
Java LinkedList

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
与 ArrayList 相比,LinkedList 的增加和删除对操作效率更高,而查找和修改的操作效率较低。

以下情况使用 LinkedList :
你需要通过循环迭代来访问列表中的某些元素。
需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

package com.company;


import java.util.LinkedList;

public class Main {

    public static void main(String[] args) {
        // 实例化对象
        LinkedList<String> sites = new LinkedList<String>();
        sites.add("Google");
        sites.add("Runoob");
        sites.add("Taobao");
        sites.add("Weibo");
        System.out.println(sites);
        //末尾添加元素
        sites.addLast("Wiki");
        System.out.println(sites);
        // 使用 removeFirst() 移除头部元素
        sites.removeFirst();
        System.out.println(sites);
        // 使用 getFirst() 获取头部元素
        System.out.println(sites.getFirst());
        // 使用 getLast() 获取尾部元素
        System.out.println(sites.getLast());
        //迭代元素
        for (int size = sites.size(), i = 0; i < size; i++) {
            System.out.println(sites.get(i));
        }
    }
}



方法三: 哈希表
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值