Leetcode刷题 几数之和

本文介绍了LeetCode中关于数之和的题目,包括两数之和、三数之和、四数之和的解题方法。对于两数之和,提出了双指针法和HashMap法,强调了时间复杂度和空间复杂度。在三数之和与四数之和的问题上,通过一层或两层遍历结合双指针,并注意在遍历过程中进行去重操作,以达到O(n^2)的时间复杂度和线性空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

两数之和 leetcode.1

1.正常的双指针
代码。

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

暴力法,两次遍历
时间复杂度:O(n^2)
空间复杂度:O(1)

2.使用hashmap

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> map = new HashMap<>();
        int []result = {0,0};
        for(int i =0;i<nums.length;i++)
        {
            int v = target -  nums[i];
            if(map.containsKey(v) && i!= map.get(v))
            {
                result[0] = map.get(v);
                result[1] = i;
            }
            map.put(nums[i], i);
        }
        return result;
    }
}
三数之和 leetcode.15

一层遍历之后用双指针,重点在于,结果是不能重复的数组,所以要进行去重。在遍历和双指针移动的过程中都需要去重。

class Solution {
    public 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;

            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;
    }
}

时间复杂度是O(n^2)
空间复杂度为O(n)

四数之和 leetcode.18

两层遍历,再用双指针。同样需要注意不可以重复,在每次遍历和每次移动指针的时候都需要去重。

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {

        List<List<Integer>> result = new ArrayList<>();
        //先排序
        Arrays.sort(nums);
        for (int i = 0;i < nums.length - 2;i ++) {
            // 去除指针i可能的重复情况
            if (i != 0 && nums[i] == nums[i-1]) {
                continue;
            }
            for (int j = i + 1;j < nums.length;j ++) {
                // 去除j可能重复的情况
                if (j != i + 1 && nums[j] == nums[j-1]) {
                    continue;
                }
                int left = j + 1;
                int right = nums.length -1;

                while (left < right) {
                    // 不满足条件或者重复的,继续遍历
                    if ((left != j + 1 && nums[left] == nums[left-1]) || nums[i] + nums[j] + nums[left] + nums[right] < target) {
                        left ++;
                    } else if ((right != nums.length -1 && nums[right] == nums[right + 1]) || nums[i] + nums[j] + nums[left] + nums[right] > target) {
                        right --;
                    } else {
                        List<Integer> list = new ArrayList<>();
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(nums[left]);
                        list.add(nums[right]);

                        result.add(list);
                        // 满足条件的,进入下一次遍历
                        left ++;
                        right --;
                    }
                }
            }
        }
        return result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值