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

Leetcode刷题

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

Untitled

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/**
* 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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 可以看成是一个容器,创建之后里面的内容是可变的。当我们在拼接字符串和反转字符串的时候会使用到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
2
3
4
5
6
//1.创建一个对象,并指定中间的间隔符号
StringJoiner sj = new StringJoiner("---");
//2.添加元素
sj.add("aaa").add("bbb").add("ccc");
//3.打印结果
System.out.println(sj);//aaa---bbb---ccc
1
2
3
4
5
6
7
8
9
10
//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. ==号比较的到底是什么?

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

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

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


2024.2.25 LeetCode刷题+Java基础(String类)
https://fulequn.github.io/2024/02/Article202402251/
作者
Fulequn
发布于
2024年2月25日
许可协议