【Java算法基础题1.2】

文章介绍了几个常见的Java数组算法问题,包括将有序数组转换为二叉搜索树、生成杨辉三角、买卖股票的最佳时机以及找出数组中只出现一次和多数的数字。通过递归、HashMap和异或运算等方法提供了解决方案,并分析了时间复杂度。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

Java 数组算法题是程序员面试中常见的题型之一,也是日常编程实践中经常涉及到的问题。掌握 Java 数组算法可以帮助开发人员更好地处理和操作数据,并提高程序的效率和可读性。

在本篇博客中,我将介绍几个常见的 Java 数组算法问题,并提供相应的解决方案。

希望通过本篇博客的学习,您能够更加熟练地处理和操作 Java 数组数据,提高自己在程序开发领域的技能水平。

一、将有序数组转换成二叉搜索树?

108. 将有序数组转换为二叉搜索树

难度一般

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树

代码展示:(采用递归的方式去生成左右子树)

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
      return buildBST(nums,0,nums.length-1);
    }
    private TreeNode buildBST(int[] nums,int left,int right){
       if(left>right){
           return null;
       }
       int mid= (left+right)/2;
       TreeNode root =new TreeNode(nums[mid]);
       root.left=buildBST(nums,left,mid-1);
       root.right=buildBST(nums,mid+1,right);
       return root;
    }
}

关于这题介绍:

采用递归的方法来构建一个高度平衡的二叉搜索树。由于给定的数组已经排好序,不妨以数组的中间元素作为根节点,然后将数组分成左右两个子数组,分别递归构建左右子树,最终组合起来形成完整的二叉搜索树。

具体地,假设当前递归到区间 [left, right],则中间元素应该是 nums[(left+right)/2]。然后可以递归构建左右子树,左子树对应区间 [left, mid-1],右子树对应区间 [mid+1,right]。递归下去直到区间不合法时返回空节点。时间复杂度为 O(n),其中 n 是数组长度。

二、杨辉三角

118. 杨辉三角

难度简单

给定一个非负整数 numRows生成「杨辉三角」的前 numRows 行。

在「杨辉三角」中,每个数是它左上方和右上方的数的和。

代码展示:

class Solution {
    public List<List<Integer>> generate(int numRows) {
       int[][] triangle=new int[numRows][numRows];
       for(int i=0;i<numRows;i++){
           for(int j=0;j<=i;j++){
               if(j==0||j==i){
                   triangle[i][j]=1;
               }else{
                   triangle[i][j]=triangle[i-1][j-1]+triangle[i-1][j];
               }
           }
       }
       List<List<Integer>> result =new ArrayList<>();
       for(int i=0;i<numRows;i++){
           List<Integer> row =new ArrayList<>();
           for(int j=0;j<=i;j++){
               row.add(triangle[i][j]);
           }
           result.add(row);
       }
     return result;
  }
}

可以使用一个二维数组来生成杨辉三角,其中第 i 行有 i 个元素。首先,设置第一行的值为 1。然后,从第二行开始,每个元素都是上一行相邻两个元素之和。最后,将生成的二维数组转换成 ArrayList<ArrayList<Integer>> 类型即可 ,时间复杂度:O(n^2),其中 n 是所需生成的杨辉三角的行数。空间复杂度:O(n^2)。

三,买卖股票的最佳时机

121. 买卖股票的最佳时机

难度简单

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 

代码展示:(小型dp)

class Solution {
    public int maxProfit(int[] prices) {
        int[] dp=new int[prices.length];
        int minprice = prices[0];
        for(int i=1;i<prices.length;i++){
            minprice=Math.min(minprice,prices[i]);
            dp[i]=Math.max(dp[i-1],(prices[i]-minprice));
        }
        return dp[prices.length-1];
    }
}

对于 dp[i],可以选择卖出或不卖出,因此需要取它的两个可能值的最大值。

时间复杂度为 O(n),空间复杂度为 O(n)。

 

四,只出现一次的数字

136. 只出现一次的数字

难度简单

给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

代码展示:(HashMap解决)

class Solution {
    public int singleNumber(int[] nums) {
       Map<Integer,Integer> map = new HashMap<>();
       for(int i=0;i<nums.length;i++){
           if(map.containsKey(nums[i])){
               map.put(nums[i],2);
           }else{
               map.put(nums[i],1);
           }
       }
       int result=0;
       for(int key :map.keySet()){
           if(map.get(key)==1){
               result=key;
               break;
           }
       }
       return result;
       
    }
}

合理利用HashMap相关知识

HashMap 是 Java 集合框架中的一种数据结构,它用于存储键值对 (key-value pair)。HashMap 的主要作用是根据 key 查找 value,在时间复杂度为 O(1) 时间进行快速查找,这使得 HashMap 成为许多实际应用程序中经常使用的集合类型之一。

在 HashMap 中,每个键都映射到一个唯一的值上。Hash 表通过将 key 映射到索引来实现快速搜索,具体来说,Hash 表就是由指向整个 key-value 对的链表的数组(即桶)构成的。

HashMap 实现了 Map 接口,提供了排序、检索、插入和删除等方法。与其他类似实现不同的是,HashMap 允许 null 值和 null 键。同时,由于 HashMap 是非线程安全的,可以使用 Hashtable 或 ConcurrentHashMap 来替代其线程安全的版本。

常见的 HashMap 方法包括 put(key, value) 将 key 和 value 插入 HashMap,get(key) 根据 key 获取相应的 value,remove(key) 根据 key 删除 entry 等。

需要注意的是,在使用自定义对象作为 HashMap 的 key 时,需要正确实现该对象的 hashCode() 和 equals() 方法,否则会出现 Hash 冲突和无法正确查找的问题。

代码展示二:(异或实现)

class Solution {
    public int singleNumber(int[] nums) {
      int result =0;
      for(int num : nums){
          result^=num;
      }
      return result;
    }
}

异或真的很舒服:

异或(XOR)是一种逻辑运算,通常用符号 ^ 表示。异或运算的规则是:两个二进制位相同为 0,不同为 1。

例如,对于两个二进制数 1010 和 1100 进行异或运算,得到的结果为 0110。

异或运算有一些特殊性质,使它在编程中经常被使用:

  1. 交换律:a ^ b = b ^ a
  2. 结合律:(a ^ b) ^ c = a ^ (b ^ c)
  3. 自反性:a ^ a = 0
  4. 恒等式:a ^ 0 = a

其中第 1 条和第 2 条性质保证了对于多个数进行异或操作时,任意顺序得到的结果都是相同的;第 3 条性质保证了对于任意数与自己进行异或运算的结果都为 0;第 4 条性质保证了对于任意数与 0 进行异或运算的结果都为它本身。

在计算机领域,异或运算常被用于:

  1. 单独出现的一些数字,如找出只出现一次的元素;
  2. 交换两个变量的值,不需要额外引入临时变量;
  3. 校验数据的完整性。

五,多数元素

169. 多数元素

难度简单

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

代码实现:

class Solution {
    public int majorityElement(int[] nums) {
       Map<Integer,Integer> map = new HashMap<>();
       int result = 0 ;
       for(int num :nums){
           if(map.containsKey(num)){
               map.put(num,map.get(num)+1);
           }else{
               map.put(num,1);
           }
           if(map.get(num)>nums.length/2){
               result=num; 
               break;
           }
       }
       return result;
    }
}

简单hash表实现 

总结

上面有一些简单数组题的实现方法,希望能帮到你加深对数组的理解

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值