java数组+Leecode数组

1. 声明数组
声明数组:在Java中,可以使用以下语法声明数组:dataType[] arrayName;。例如,要声明一个整数数组,可以写int[] myArray;。

实例化数组:声明数组后,需要使用new关键字为其分配内存。例如:myArray = new int[10];。这将创建一个可以存储10个整数的数组。

初始化数组:可以在声明数组时初始化它,例如:int[] myArray = {1, 2, 3, 4, 5};。也可以在创建数组后单独初始化每个元素,例如:myArray[0] = 1;。
注意:声明时初始化:在声明数组的同时,就为数组分配空间并赋值。例如:
        int[] arr = {1, 2, 3};
        先声明,后初始化:先声明一个数组,然后再为数组的每个元素分配空间并赋值。例如:
        java
        Copy code
        int[] arr = new int[3];
        arr[0] = 1;
        arr[1] = 2;
        arr[2] = 3;
        不能将两种方法混合:int [] arr = new int[3];
                        arr = {1,2,3};
                        这种方法是错误的

        访问数组元素:可以使用数组索引来访问数组元素。数组的索引从0开始,所以第一个元素的索引是0,第二个元素的索引是1,依此类推。例如,myArray[0]将访问数组的第一个元素。

        数组长度:可以使用arrayName.length获取数组的长度。例如,myArray.length将返回数组myArray的长度。

        多维数组:Java支持多维数组,最常见的是二维数组。例如,int[][] my2DArray = new int[10][5];创建了一个10行5列的二维数组。

        遍历数组:可以使用for循环或者for-each循环来遍历数组。例如:
        for(int i=0; i<myArray.length; i++) {
            System.out.println(myArray[i]);
        }
        或者

        for(int num : myArray) {
            System.out.println(num);
        }*/
2.Arrays常用操作
//1.sort():对数组进行排序
        int[] arr3 = {3,2,1};
        Arrays.sort(arr3);
     /*   arr现在是{1, 2, 3}*/

        //2.toString():返回数组的字符串表示形式。
        String str = Arrays.toString(arr3);
        // str现在是"[1, 2, 3]"
        /*在这个例子中,str是一个字符串,它的值是"[1, 2, 3]"。这个字符串的长度是9,因为它包含了9个字符:一个开方括号,三个数字,两个逗号,两个空格,和一个闭方括号。

        每个数字在这个字符串中都是字符的一部分,而不是一个独立的整数。在Java中,字符串是由字符组成的,所以str中的"1"、"2"和"3"都是字符,而不是整数。

        如果你想从这个字符串中获取整数,你需要进行一些处理,例如使用split()方法分割字符串,然后将每个分割后的字符串转换为整数。例如:*/

        /*String str = "[1, 2, 3]";*/
        str = str.replaceAll("\\[|\\]|\\s", ""); // 移除方括号和空格
        //注意split返回的是string的数组
        String[] numbers = str.split(","); // 使用逗号分割字符串
        for (String number : numbers) {
            int num = Integer.parseInt(number); // 将字符串转换为整数
            System.out.println(num);
        }
        /*这段代码将输出:

        Copy code
        1
        2
        3
        这样,你就可以从字符串中获取到每个数字作为一个整数。*/

        //3.binarySearch():在已排序的数组中查找指定的元素。如果找到,返回元素的索引;如果找不到,返回负值。
        int number = Arrays.binarySearch(arr3,2);
        //number = 1

        //4.equals()判断两个数组是否完全一致
        int[] arr4 = {3,2,1};
        boolean isEqual = Arrays.equals(arr4,arr3);
        //isEqual = ture

        //5.fill():使用指定的值填充整个数组或者数组的一部分。
        Arrays.fill(arr4,1);
        /*arr4 = {1,1,1}*/

        //6.copyOf():复制数组的一部分或全部到一个新数组。
        int[] arr5 = Arrays.copyOf(arr3,arr3.length);
        /*arr5 = {3,2,1}*/

    }


1. 两数之和

在Java中,我们可以使用HashMap来存储数组中每个元素的值和它们对应的索引。这样,对于数组中的每个元素x,我们可以快速检查哈希表中是否存在一个键值为target - x的元素。如果存在,那么我们找到了一对数,它们的和为target

import java.util.HashMap;

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 创建一个HashMap来存储之前遍历过的数字和它们对应的索引
        HashMap<Integer, Integer> map = new HashMap<>();
        // 遍历数组中的每个元素
        for (int i = 0; i < nums.length; i++) {
            // 计算当前元素与目标值之间的差
            int complement = target - nums[i];
            // 检查这个差值是否已经在Map中,如果是,直接返回当前索引和差值对应的索引
            if (map.containsKey(complement)) {
                return new int[] { map.get(complement), i };
            }
            // 如果没有找到,将当前元素的值和索引存入Map中,以便后续查找
            map.put(nums[i], i);
        }
        // 如果没有找到符合条件的两个数,则抛出异常
        return new int[] {};
    }
}
49. 字母异位词分组

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

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        if (strs == null || strs.length == 0) {
            return new ArrayList<>();
        }
        Map<String, List<String>> map = new HashMap<>();
        for (String s : strs) {
            char[] ca = s.toCharArray();
            Arrays.sort(ca);
            String key = String.valueOf(ca);
            if (!map.containsKey(key)) {
                map.put(key, new ArrayList<>());
            }
            map.get(key).add(s);
        }
        return new ArrayList<>(map.values());
    }
}

为了解决这个问题,我们可以采用一个高效的策略:对每个字符串按照字符排序,然后使用排序后的字符串作为键,将原始字符串添加到对应的列表中。这样,所有字母异位词都会有相同的排序字符串作为键,从而被归类到同一个列表中。

具体步骤如下:

  1. 创建一个哈希表(HashMap),键是字符串,值是字符串列表,用于存放归类后的字母异位词。
  2. 遍历给定的字符串数组strs
    • 对每个字符串进行排序。
    • 检查排序后的字符串是否已经作为键存在于哈希表中。
    • 如果存在,将原字符串添加到对应的列表中。
    • 如果不存在,创建一个新的列表,并将原字符串添加到列表中,然后将列表作为值,排序后的字符串作为键存入哈希表中。
  3. 最后,返回哈希表中所有值的集合,这就是分组后的字母异位词列表。
128. 最长连续序列

要实现一个时间复杂度为O(n)的算法来解决这个问题,我们可以利用哈希表(在Java中是HashSet)来快速查找数组中的元素。基本思路是这样的:

  1. 首先,将所有的元素放入哈希表中,这样就可以在O(1)的时间复杂度内判断一个元素是否存在。
  2. 然后,遍历数组中的每个元素,对于每个元素,我们尝试向两边扩展序列,查看比当前元素小1的元素和比当前元素大1的元素是否存在于哈希表中,如果存在,就继续向该方向扩展,并从哈希表中移除已经访问过的元素,以避免重复计算。
  3. 记录并更新最长连续序列的长度。

这里需要注意的是,我们只从序列的第一个元素开始扩展,即只有当一个元素的前一个元素不存在于哈希表中时,才开始扩展。这样可以确保我们每个序列只会被扩展一次,保证了算法的时间复杂度为O(n)。

class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> numSet = new HashSet<>();
        //将所有的不重复的num加入到set中去。
        for(int num: nums) {
            numSet.add(num);
        }

        //最长的连续个数
        int longestStreak = 0;


        //遍历所有的set
        for(int num : numSet) {
             只有当num的前一个元素不存在时,才开始向后寻找连续序列
            if(!numSet.contains(num - 1)) {
                int curNum = num;
                //将当前最长序列变成1,就是起始位置。
                int curStreak = 1;

                //在set中不断找比当前数大1的数
                while(numSet.contains(curNum + 1)) {
                    //如果有,更新当前数,并且将当前最长的序列长度再加1
                    curNum += 1;
                    curStreak += 1;
                }

                //找到了一个最长序列,看看是不是整个nums数组最长的。
                longestStreak = Math.max(longestStreak, curStreak);
            }
        }

        return longestStreak;
    }
}

// 只有当num的前一个元素不存在时,才开始向后寻找连续序列 为什么?

ChatGPT

ChatGPT

这个策略是为了确保算法的效率和防止重复计算,使得时间复杂度能够保持在O(n)。让我们详细解释一下这个过程。

当我们从一个数开始寻找连续序列时,如果这个数的前一个数也在数组中,意味着这个数已经是某个连续序列的一部分了。如果我们从这个数开始向两边扩展,那么这个连续序列的前半部分实际上是被重复计算的,因为从前一个数开始扩展时,这部分已经被计算过一次了。

通过只从序列的“起点”开始扩展(即这个数的前一个数不在数组中,表明这个数可能是一个连续序列的最小值),我们可以确保:

  1. 避免重复计算:每个连续序列只会被计算一次,即从它的最小值开始向上寻找连续的数。这样,每个数字在寻找连续序列时只会被访问和计算一次,避免了不必要的重复操作。

  2. 效率最高:由于每个序列只被计算一次,且哈希表的查找操作是O(1)的,因此整个算法可以在O(n)的时间复杂度内完成。这里n是数组中元素的数量。我们通过哈希表一次性将所有元素加入,然后遍历数组时,每个元素最多被访问一次(除非它是某个连续序列的一部分,在这种情况下,它在寻找过程中只被计算一次)。

举个例子,考虑数组[3, 4, 2, 1]。按照上述策略,当我们遇到3时,会检查2是否在集合中。因为2存在,我们就跳过3不做处理(因为如果2存在,那么从2开始的序列肯定比从3开始的要长)。当我们遇到4时,检查3发现存在,同样跳过。当我们到2时,发现1不存在,意味着2可能是一个连续序列的起点,于是从2开始向上寻找,直到4,形成连续序列[2, 3, 4]。最后,当处理到1时,由于它的前一个数不存在,我们知道它是另一个序列的起点,但因为它自己就构成了一个长度为1的序列,所以这一步实际上没有扩展的必要。

240. 搜索二维矩阵

思路:

由于矩阵的行和列都是升序排列的,我们可以从右上角开始搜索。根据目标值与当前元素的比较,我们可以排除一整行或一整列。

  1. 初始化坐标: 将行坐标设置为0,列坐标设置为矩阵的最后一列。
  2. 比较并移动:
    • 如果目标值等于当前元素,则返回 true
    • 如果目标值小于当前元素,则向左移动一列。
    • 如果目标值大于当前元素,则向下移动一行。
  3. 重复步骤2: 直到行坐标超出范围或列坐标超出范围。

但是如果从左上角开始搜索,则当目标值大于当前元素时,我们无法确定是向右移动还是向下移动,因为两个方向的元素都可能大于当前元素。

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        int m = matrix.length, n = matrix[0].length;
        int row = 0, col = n - 1;

        while (row < m && col >= 0) {
            if (matrix[row][col] == target) {
                return true; // 找到目标值
            } else if (matrix[row][col] < target) {
                row++; // 向下移动
            } else {
                col--; // 向左移动
            }
        }

        return false; // 没有找到目标值
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值