0705刷题记录

合并两个有序数组

https://leetcode.cn/problems/merge-sorted-array/

题目

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。

请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

  • 示例 1:

​ 输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
​ 输出:[1,2,2,3,5,6]
​ 解释:需要合并 [1,2,3] 和 [2,5,6] 。
​ 合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

思路

把数组2替换掉数组1里的0,然后.sort()排序。

代码

class Solution {
  public void merge(int[] nums1, int m, int[] nums2, int n) {
    for (int i = 0; i != n; ++i) {
      nums1[m + i] = nums2[i];
    }
    Arrays.sort(nums1);
  }
}

环形链表

https://leetcode.cn/problems/linked-list-cycle/

题目

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例 1:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XYq9zjTn-1657018354271)(https://pic.imgdb.cn/item/62c3f9085be16ec74aa41917.png)]

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

思路

使用哈希表来存储所有已经访问过的节点。每次我们到达一个节点,如果该节点已经存在于哈希表中,则说明该链表是环形链表,否则就将该节点加入哈希表中。

代码

public class solution {
  public boolean hasCycle(ListNode head) {
    Set<ListNode> set = new HashSet<ListNode>();
    while (head != null) {
      if (!set.add(head)) {
        return true;
      }
      head = head.next;
    }
    return true;
  }
}

三数之和

题目

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

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

  • 示例 1:

​ 输入:nums = [-1,0,1,2,-1,-4]
​ 输出:[[-1,-1,2],[-1,0,1]]

思路

标签:数组遍历
首先对数组进行排序,排序后固定一个数 nums[i],再使用左右指针指向nums[i]后面的两端,数字分别为 nums[L]和 nums[R],计算三个数的和 sum 判断是否满足为 0,满足则添加进结果集
如果 nums[i]大于 0,则三数之和必然无法等于 0,结束循环
如果 nums[i] = nums[i-1],则说明该数字重复,会导致结果重复,所以应该跳过
当 sum = 0 时,nums[L] = nums[L+1] 则会导致结果重复,应该跳过,L++
当 sum = 0 时,nums[R] = nums[R−1] 则会导致结果重复,应该跳过,R–

代码

class Solution1 {
  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;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值