ARTS打卡 - 2023-04-W2

102 阅读2分钟

Algorithm

回文链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        if (head == null || head.next == null) {
            return true;
        }
        ListNode n1 = head;
        ListNode n2 = head;
        while (n2.next != null && n2.next.next != null) {
            n1 = n1.next;
            n2 = n2.next.next;
        }
        n2 = n1.next;
        n1.next = null;
        ListNode n3 = null;
        while (n2 != null) {
            n3 = n2.next;
            n2.next = n1;
            n1 = n2;
            n2 = n3;
        }
        n3 = n1;
        n2 = head;
        boolean res = true;
        while (n1 != null && n2 != null) {
            if (n1.val != n2.val) {
                res = false;
                break;
            }
            n1 = n1.next;
            n2 = n2.next;
        }
        n1 = n3.next;
        n3.next = null;
        while (n1 != null) {
            n2 = n1.next;
            n1.next = n3;
            n3 = n1;
            n1 = n2;
        }
        return res;
    }
}

Review

Kotlin Lateinit vs by Lazy

Tip

Kotlin中,为什么 by lazy修饰的对象必须是val类型的,Lateinit 修饰的对象必须是var类型的?

  1. by lazy修饰的对象必须是val类型的,因为它只会被初始化一次,之后就不会改变。如果我们将其定义为var类型的,那么就可以对它们进行重新赋值,这显然违背了lazy的初衷。

  2. Lateinit修饰的对象必须是var类型的,因为该属性不会被立即初始化,而是在对象被实例化之后进行初始化。如果我们将其定义为val类型的,那么该属性就只能被赋值一次,在后续的运行中就无法修改,这与lateinit的初衷也是相悖的。

为什么不能对 Int 等基本类型 lateinit 修饰,而 by lazy 可以? 

  1. lateinit:它主要是为了解决在Kotlin中使用依赖注入框架时,需要在类的成员变量中先声明,在构造函数中初始化的问题。因此这个特性只能用在类的属性中,需要用var表示可变,并且只能用于类对象类型,而不能用于基本数据类型。

  2. lazy:它主要是为了延迟初始化,在需要使用到变量时再进行初始化,以提高程序的性能。因此可以使用在任何变量中,包括基本数据类型,它的特性是只计算一次,之后可重复使用,相当于一种“缓存”机制,所以可以使用val表示为不可变变量。

综合来看,lateinit主要是为了解决类属性的初始化问题,而lazy是为了延迟初始化和提高程序性能。因此,在设计上lateinit只能用于类对象类型的属性中,而不能用于基本数据类型,而lazy则没有这个限制。

Share

最通俗易懂的计算机底层教学,二进制到汇编学习