刷题日记2--leetcode篇(Java)

本文介绍了如何用Java解决两个问题:生成一个顺时针螺旋排列的矩阵和查找是否存在三数之和为零的不重复三元组。重点讲解了循环不变量在螺旋矩阵生成中的应用以及三数和问题的高效算法设计。
摘要由CSDN通过智能技术生成

1、螺旋矩阵(59题)

看的代码随想录老师的讲解!

题目描述:给你一个正整数 n,生成一个包含 1 到 n² 所有元素,且元素按顺时针顺序螺旋排列的n * n正方形矩阵matrix。

输入:n=3

输出:[ [1, 2, 3], [8, 9, 4], [7, 6, 5] ]

解法:

这个题确实很绕,但其实只要明白循环不变量这个准则就可以解决这道题。即使用统一的规则去处理,下面讲解详细做法。

对于螺旋矩阵,其大小为 n * n ,一共要转[n/2]圈。

如果n能够被2整除,则中间是由四个数字组成的正方形圈;如果n除2余1,那么最中间只有一个点。如果中间是四个数字组成的正方形圈,和外圈按照一样的原则处理就行,如果中间是一个点,那么将该点赋值为n²即可。

对于每条边的处理,我们采用左闭右开的原则,将拐角处的点都交由下一条边去处理,如图所示。强调一点,如果你使用了这种规则,那么以后所有边处理规则都按照这个来处理,遵循循环不变量原则!!计算出一共要转几圈,然后对每一圈都采用该计算方式。

Java代码:

class Solution {
    public int[][] generateMatrix(int n) {
        int loop = 0;
        int[][] res = new int[n][n];
        int start = 0;
        int count = 1;
        int i, j;

        while(loop++< n/2){
            for(j = start; j < n-loop; j++){
                res[start][j] = count++;
            }
            for(i=start; i<n-loop;i++){
                res[i][j] = count++;
            }
            for(;j>=loop;j--){
                res[i][j] = count++;
            }
            for(;i>=loop;i--){
                res[i][j] = count++;
            }
            start++;
        }
        if(n%2 == 1){
            res[start][start] = count;
        }

        return res;
    }
}

2、三数之和(15题)

给你一个整数数组 nums ,判断是否存在三元组[ nums[i], nums[j], nums[k] ]满足 i != j,i != k且 j !=k,同时还满足 nums[i] + nums[j] + nums[k] = 0。请你返回所有和为 0 且不重复的三元组。

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

解法:三元数组,如果数组长度小于3,那么直接返回空列表。先对数组排序(因为不存在重复的三元组,所以排序后,如果数值相同的数字肯定是相邻的,这样处理起来更方便。)。

然后设置3个指针,i 指针指定每次循环时第一个指针所指向的位置,循环结束后 i 指针指向下一个位置;left 指针在 i+1 位置, 即每次都指向i指针后面的位置;right 指针指向数组末端的位置。内嵌套循环即 left < right 时即可循环,设置 sum 值为 nums[i] + nums[j] + nums[k],如果 sum=0,判断 left 指针下一个位置和当前位置值是否相同,right 指针前一个位置和当前位置值是否相同,如果相同的话就跳过重复的元素。如果sum<0,说明当前值小了,指针 left 右移;如果sum>0,说明当前值大了,指针 right 左移。综上即可实现。代码如下:

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

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        if (nums.length < 3) {
            return res; // 如果数组长度小于 3,直接返回空列表
        }
        Arrays.sort(nums); // 对数组进行排序,方便后续处理
        for (int i = 0; i < nums.length - 2; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue; // 避免重复计算相同的元素
            }
            int left = i + 1;
            int right = nums.length - 1;
            while (left < right) {
                int sum = nums[i] + nums[left] + nums[right];
                if (sum == 0) {
                    res.add(Arrays.asList(nums[i], nums[left], nums[right]));
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++; // 跳过重复的元素
                    }
                    while (left < right && nums[right] == nums[right - 1]) {
                        right--; // 跳过重复的元素
                    }
                    left++;
                    right--;
                } else if (sum < 0) {
                    left++;
                } else {
                    right--;
                }
            }
        }
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值