2024.2.25 LeetCode刷题+Java基础(String类)

Leetcode刷题

2. 两数相加 - 力扣(LeetCode)

Untitled

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        // head用于记录结果,tail用于更新链表
        ListNode head = null, tail = null;
        int carry = 0;  //进位
        // 只有其中有一个为null,就退出循环。
        // 因为考虑了给短链添加0,所以只要长链后面没有东西,就退出了
        while(l1 != null || l2 != null){
            // 如果是短链,就补0
            int n1 = (l1 != null? l1.val: 0); 
            int n2 = (l2 != null? l2.val: 0);
            // 记录对应位置相加的结果
            int sum = n1+n2+carry; 
            // 链初始化
            if(head == null){
                // 对10取余是当前位的值,除以10是进位值
                head = tail = new ListNode(sum % 10);
            }else{  // 后面添加节点
                // 记录
                tail.next = new ListNode(sum % 10);
                tail = tail.next;
            }
            // 得到进位值
            carry = sum / 10;
            // 定位到下一位置节点,用于遍历
            // 短链后面的值都为null,就不需要向下传递了
            if(l1 != null){
                l1 = l1.next;
            }
            if(l2 != null){
                l2 = l2.next;
            }
        }
        // 如果最后存在进位,要添加到结果的结尾
        if(carry > 0){
            tail.next = new ListNode(carry);
        }
        return head;
    }
}

67. 二进制求和 - 力扣(LeetCode)

Untitled

class Solution {
    public String addBinary(String a, String b) {
        // 用于记录最终结果
        StringBuffer result = new StringBuffer();
        // 记录最长值n,carry表示进位
        int n = Math.max(a.length(), b.length()), carry = 0;
        // 逆序遍历
        for (int i = 0; i < n; i++) {
            // 从后面开始判断
            // 添加a对应位置,防止出现越界异常
            carry += i < a.length() ? (a.charAt(a.length() - 1 - i) - '0') : 0;
            // 添加b对应位置
            carry += i < b.length() ? (b.charAt(b.length() - 1 - i) - '0') : 0;
            // 添加对应位置的字符
            result.append((char) (carry % 2 + '0'));
            // 获取进位值
            carry /= 2;
        }
        // 有进位则最后也进行添加
        if (carry > 0) {
            result.append('1');
        }
        // 反转字符串
        result.reverse();
        // 返回String
        return result.toString();
    }
}

Untitled

这个做法和我想到一起去了,既然String的操作速度会慢,那么我们可以使用纯数字的计算来代替,然后记录住这个数值,然后再转化为String。

下面这个图片中的思路中,最值得学习的就是,如果我们想要控制a和b的长度格式始终为a<b,我们就可以在获取对应的长度之后,然后再根据对应的参数的大小,重新调用一下这个函数。感觉有点相当于函数的自我修正。

Java基础

1 String类

1.1 String类概述

String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例。也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象。String 类在 java.lang 包下,所以使用的时候不需要导包!

1.2 String类的特点

  • 字符串不可变,它们的值在创建后不能被更改
  • 虽然 String 的值是不可变的,但是它们可以被共享
  • 字符串效果上相当于字符数组( char[] ),但是底层原理是字节数组( byte[] )

1.3 String类的构造方法

常用的构造方法

方法名说明
public String()创建一个空白字符串对象,不含有任何内容
public String(char[] chs)根据字符数组的内容,来创建字符串对象
public String(byte[] bys)根据字节数组的内容,来创建字符串对象
String s = “abc”;直接赋值的方式创建字符串对象,内容就是abc

1.4 创建字符串对象两种方式的区别

  • 通过构造方法创建

    通过 new 创建的字符串对象,每一次 new 都会申请一个内存空间,虽然内容相同,但是地址值不同。

  • 直接赋值方式创建

    以“”方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM 都只会建立一个 String 对象,并在字符串池中维护。

1.5 StringBuilder

StringBuilder 可以看成是一个容器,创建之后里面的内容是可变的。当我们在拼接字符串和反转字符串的时候会使用到。

public class StringBuilderDemo3 {
    public static void main(String[] args) {
        //1.创建对象
        StringBuilder sb = new StringBuilder("abc");

        //2.添加元素
        /*sb.append(1);
        sb.append(2.3);
        sb.append(true);*/

        //反转
        sb.reverse();

        //获取长度
        int len = sb.length();
        System.out.println(len);


        //打印
        //普及:
        //因为StringBuilder是Java已经写好的类
        //java在底层对他做了一些特殊处理。
        //打印对象不是地址值而是属性值。
        System.out.println(sb);
    }
}

1.6 StringJoiner

  • StringJoiner跟StringBuilder一样,也可以看成是一个容器,创建之后里面的内容是可变的。
  • 作用:提高字符串的操作效率,而且代码编写特别简洁,但是目前市场上很少有人用。
  • JDK8出现的

基本使用:

//1.创建一个对象,并指定中间的间隔符号
StringJoiner sj = new StringJoiner("---");
//2.添加元素
sj.add("aaa").add("bbb").add("ccc");
//3.打印结果
System.out.println(sj);//aaa---bbb---ccc
//1.创建对象
StringJoiner sj = new StringJoiner(", ","[","]");
//2.添加元素
sj.add("aaa").add("bbb").add("ccc");
int len = sj.length();
System.out.println(len);//15
//3.打印
System.out.println(sj);//[aaa, bbb, ccc]
String str = sj.toString();
System.out.println(str);//[aaa, bbb, ccc]

关于字符串的小扩展

  1. 字符串存储的内存原理

    String s = “abc”;直接赋值

    特点:

    此时字符串abc是存在字符串常量池中的。

    先检查字符串常量池中有没有字符串abc,如果有,不会创建新的,而是直接复用。如果没有abc,才会创建一个新的。

    所以,直接赋值的方式,代码简单,而且节约内存。

  2. new出来的字符串

    看到new关键字,一定是在堆里面开辟了一个小空间。

    String s1 = new String(“abc”);

    String s2 = “abc”;

    s1记录的是new出来的,在堆里面的地址值。

    s2是直接赋值的,所以记录的是字符串常量池中的地址值。

  3. ==号比较的到底是什么?

    如果比较的是基本数据类型:比的是具体的数值是否相等。

    如果比较的是引用数据类型:比的是地址值是否相等。

    结论:==只能用于比较基本数据类型。不能比较引用数据类型。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!