bigdecimal 判断是否为空_七十、反转和合并链表、 链表有环的判断

本文总结了链表操作的常见题目,包括LeetCode的206题(反转链表)、141题(判断链表有环)、21题(合并两个有序链表)和23题(合并k个排序链表)。详细解释了使用迭代和递归的方法解决这些问题,并探讨了空间和时间复杂度。

282cf8dbabd2fb5ee34a8aeafe2fdd3d.png

「@Author:Runsen」

❝ 编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化。 「---- Runsen」

最近在重新梳理学算法的知识,本文为链表常见操作复习的总结文章,会讲解常见的链表题目实现思路及附上答案,这些题目在leetcode上对应的题号也有给出,好好学习算法吧~

  • 单链表反转
  • 链表中环的检测
  • 两个有序的链表合并
  • K个有序的链表合并

leetcode 对应题号:206,141,21,23

LeetCode 第 206 题:反转链表

反转一个单链表。

示例: 
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL 

题目不难,定义三个变量pre、cur、cur.next,分别记录上一个结点,当前结点、下一个结点。

反转一个单链表需要当前节点的next指针指向上一个结点pre,当前节点的指针指向下一个结点,上一个结点的指针指向当前节点。

通过迭代,依次反转结点指向。具体代码如下

class Solution:
    def reverseList(self, head):
        cur, prev = head, None
        while cur:
            cur.next, prev, cur = prev, cur, cur.next
        return prev

LeetCode 第 141 题:判断链表中是否有环

fe4c9cb96eb67ce098c59eb8a1c2146f.png

遍历整个数组, 给出的数据包含在集合中则说明有环, 返回 True; 若遍历完毕, 则说明无环, 返回 False,如果用列表也是一样。

「暴力解法」

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        """
        暴力法:通过遍历链表,用set来存储访问的节点,如果在set出现一样的节点,说明有坏,时间复杂度O(n)
        :type head: ListNode
        :rtype: bool
        """
        st = set()
        while head:
            if head in st:
                return True
            st.add(head)
            head = head.next
        return False


      # 下面是列表
        l = []
        while head:
            if head in l:
                return True
            else:
                l.append(head)
                head = head.next
        return False   

80f385a3f093bae1cea81033ff2568c3.png

从头遍历到尾,发现指向null,说明没环。这明显不靠谱。暴力的时间空间复杂度都是O(n)

题目要求用 空间复杂度。其实,这道题考的是「快慢指针」 空间复杂度

通过使用具有 不同速度 的快、慢两个指针遍历链表,空间复杂度可以被降低至。慢指针每次移动一步,而快指针每次移动两步。

如果列表中不存在环,最终快指针将会最先到达尾部,此时我们可以返回 false。

可以想象这样一个场景, 你和一个朋友一起散步, 你每次移动两步, 朋友每次一步, 如为单向定长道路, 你必然先到达重点. 若是环绕操场,则你们终将相遇.

class Solution(object):
    def hasCycle(self, head):
        slow = fast = head
        while slow and fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return True
        return False

LeetCode 第21题:合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例: 

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

从两链表第一个结点开始比较结点的值,取较小者作为合并链表的元素,依次进行;后面如果有一个链表为空,则直接把不为空的链表接到合并链表的后面。

这个解决的方法使用递归,如果L1为空就返回L2,L2为空返回L1,L1的val<=L2的val,那么继续递归。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None


class Solution(object):
 def mergeTwoLists(self, l1, l2):
  """
  :type l1: ListNode
  :type l2: ListNode
  :rtype: ListNode
  """
  #递归的结束点就是L1或者L2为空就返回
  #如果L1为空就返回L2,L2为空返回L1
  # if not (l1 and l2):
   # return l1 if l1 else l2
  if not l1:
            return l2
        elif not l2:
            return l1
  #L1的val<=L2的val,那么继续递归
  #当前L1的next指向一个递归函数
  #意思是L1的下一个和L2哪个大,就作为当前L1的next
   elif l1.val<=l2.val:
   l1.next = self.mergeTwoLists(l1.next,l2)
   return l1
  else:
   l2.next = self.mergeTwoLists(l1,l2.next)
   return l2

递归的代码看起来是十分简洁的

c838ff869d689d77dde37121f432f9f6.png

LeetCode 第 23 题:合并 k 个排序链表

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例: 
输入:
[
 1->4->5,
 1->3->4,
 2->6
]
输出: 1->1->2->3->4->4->5->6 

第一种法就是常规暴力思路,直接将所有的元素取出,然后排个序,再重组就达到了目的。

遍历所有链表,将所有节点的值放到一个数组中。将这个数组排序,然后遍历所有元素得到正确顺序的值。用遍历得到的值,创建一个新的有序链表。

时间复杂度: ,其中 N 是节点的总数目

空间复杂度:。

排序花费空间(这取决于你选择的算法)。 创建一个新的链表花费 的空间。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None


class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode :
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """
        self.nodes = []
        head = point = ListNode(0)
        for l in lists:
            while l:
                self.nodes.append(l.val)
                l = l.next
        for x in sorted(self.nodes):
            point.next = ListNode(x)
            point = point.next
        return head.next

「人生最重要的不是所站的位置,而是内心所朝的方向。只要我在每篇博文中写得自己体会,修炼身心;在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰难,奋勇前行,不忘初心,砥砺前行,人生定会有所收获,不留遗憾 (作者:Runsen )」

❝ 本文已收录 GitHub,传送门~[1] ,里面更有大厂面试完整考点,欢迎 Star。

Reference

[1]

传送门~: https://github.com/MaoliRUNsen/runsenlearnpy100

<think>好的,用户的问题是关于如何在Java中检查BigDecimal是否为null或者“”。我需要仔细分析他们的需求,并给出准确的解决方案。 首先,用户提到了“”或者未初始化的情况。BigDecimal在Java中是一个对象,所以它可以为null,也就是未被初始化的情况。但是,用户还提到了“empty”,这里可能需要进一步明确。因为BigDecimal不像字符串那样有“字符串”的概念,但有时候用户可能认为值为0或者某些特定值(比如零)也可能被视为“”,不过根据常规理解,“empty”在这里更可能指未赋值的情况,即null。 接下来,我需要考虑用户提供的引用内容。他们引用了两个资料:第一个是关于判断字符串是否为数字的方法,其中提到null会返回false,字符串返回true。第二个是关于Hibernate Validator的使用示例,展示了如何在控制器中进行参数校验。这些引用可能帮助用户联想到类似的方法来处理BigDecimal的校验,比如使用注解或者手动检查。 用户的问题是如何检查BigDecimal是否为null或empty。根据Java的特性,BigDecimal本身没有“”状态,除非用户自定义某种条件。例如,可能认为BigDecimal.ZERO或者某个特定值(如null)视为。但根据常规情况,用户可能只是想检查是否为null,或者是否被正确初始化。 不过,用户提到“empty”可能让人困惑。需要明确的是,BigDecimal没有isEmpty()方法。所以可能的解释是用户可能希望同时检查null某些数值条件,比如值为0或者未设置值的情况。需要进一步分析用户的真实需求。 根据用户的引用[1],字符串检查中null返回false,字符串返回true,这可能类比到BigDecimal的情况,用户可能希望一个对象如果为null则视为无效,或者如果值为零则视为需要处理的情况。但需要确认用户的具体需求。 可能的解决方案包括: 1. 检查BigDecimal是否为null,这直接使用== null判断。 2. 如果用户希望检查是否为null或者零,可以使用BigDecimal.ZERO比较。 3. 如果用户有自定义的值,比如某个特定的数值,需要根据具体条件判断。 但是根据问题的描述,用户可能主要关注null的情况,而“empty”可能是一个不准确的表述。因此,需要回答如何处理null,并询问是否需要处理其他情况。 另外,用户引用了Hibernate Validator的使用,可能他们希望在参数校验时使用注解来处理BigDecimal的校验。例如,使用@NotNull或自定义的校验注解来确保BigDecimal不为null,或者满足其他条件。 总结用户可能的真实需求: - 如何判断BigDecimal对象是否为null。 - 是否有其他条件需要考虑,如值为零的情况。 - 是否可以使用校验框架(如Hibernate Validator)来自动处理这些检查。 因此,回答需要包括: 1. 基本的null检查方法。 2. 可能的零值检查(如果用户需要)。 3. 使用校验注解的例子,如@NotNull。 4. 自定义校验逻辑,比如结合@Valid自定义注解。 同时,需要生成相关问题,例如如何处理零值,或者如何使用校验框架进行验证。 需要确保回答清晰,分步骤说明,并提供代码示例,同时引用用户提供的参考资料中的相关部分,例如引用[2]中的校验示例。 最后,需要验证回答的准确性,确保代码示例正确,并且覆盖用户可能的需求场景。</think>在Java中检查BigDecimal是否为null或未初始化,需要分两种场景处理:基本类型判断校验框架整合。以下是具体实现方法: ### 一、基础判断方法 1. **null检查**(对象未初始化) ```java BigDecimal value = null; if (value == null) { System.out.println("未初始化"); } ``` 2. **零值判断**(根据业务需求) ```java BigDecimal value = BigDecimal.ZERO; if (value.compareTo(BigDecimal.ZERO) == 0) { System.out.println("值为零"); } ``` ### 二、校验框架整合(Hibernate Validator) 1. **基础注解校验** ```java public class RequestDTO { @NotNull(message = "金额不能为") private BigDecimal amount; // getter/setter } ``` 2. **自定义校验规则**(组合校验) ```java @Target({FIELD}) @Retention(RUNTIME) @Constraint(validatedBy = BigDecimalValidator.class) public @interface ValidBigDecimal { String message() default "无效金额"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } public class BigDecimalValidator implements ConstraintValidator<ValidBigDecimal, BigDecimal> { @Override public boolean isValid(BigDecimal value, ConstraintValidatorContext context) { return value != null && value.compareTo(BigDecimal.ZERO) > 0; } } ``` ### 三、综合判断工具类 ```java public class BigDecimalUtils { public static boolean isNullOrZero(BigDecimal value) { return value == null || value.compareTo(BigDecimal.ZERO) == 0; } public static boolean isInvalid(BigDecimal value) { return value == null || value.scale() < 0; // 添加其他业务规则 } } ``` [^1]: 类似字符串校验中null返回false的逻辑,数值类型的判断需要显式处理 [^2]: 校验注解的使用方式与Hibernate Validator的集成方法类似
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值