【校招VIP】Java-数据结构-字符串专题

2天前 收藏 0 评论 0 java开发

【校招VIP】Java-数据结构-字符串专题

转载声明:文章来源https://blog.csdn.net/weixin_45532984/article/details/125984603?ops_request_misc=&request_id=&biz_id=102&utm_term=java%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%9F%BA%E6%9C%AC%E6%80%A7%E8%B4%A8&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-125984603.142^v101^pc_search_result_base6&spm=1018.2226.3001.4187

一. 字符串的简单介绍
字符串
字符串是复合数据类型。在程序中经常会用到字符串及对字符串的各种操作,如字符串的连接、比较、截取、查找和替换等。Java提供了Java.lang.String类来对字符串进行这一系列的操作,以及StringBuffer,StringBuilder类.

字符串为何用final修饰
final是Java中的保留关键字,可以用来修饰类,方法和变量。其中,被final修饰的类不能被继承即不能拥有自己的子类,被final修饰方法不能被重写,final修饰的属性、变量初始化之后不能被修改。
String类的不可变性带来的好处总结主要有两点:
    1.因为String类的不可变性,才能使得JVM可以实现字符串常量池;字符串常量池可以在程序运行时节约很多内存空间,因为不同的字符串变量指向相同的字面量时,都是指向字符串常量池中的同一个对象。这样一方面能够节约内存,另一方面也提升了性能。
    2.因为String类的不可变性,从而保证了字符串对象在多线程环境下是线程安全的。如果String类是可变的,那么会引起很严重的安全问题。我们在很多情况下都是直接通过字符串传递数据,比如数据库的用户名密码、网络编程中的ip和端口,因为字符串是不可变的,所以它的值不能被修改,如果字符串是可变的,那么可以通过改变引用地址指向的值去修改字符串的值,从而导致安全漏洞

String,StringBuilder,StringBuffer区别和联系
String为字符串常量,一旦被创建就不能再进行更改
StringBuilder和为字符串变量,创建后是可以被更改的
三者的执行速度:StringBuilder>StringBuffer>String
StringBuilder是线程不安全,StringBuffer是线程安全的
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

二. 围绕字符串相关的转换
string和char的转换
String转换为char
使用String.charAt(index)(返回值为char)可以得到String中某一指定位置的char。
使用String.toCharArray()(返回值为char[])可以得到将包含整个String的char数组。这样我们就能够使用从0开始的位置索引来访问string中的任意位置的元素。

char转换为String
String s = String.valueOf('c');
string和int的转换
1. 如何将字符串String转化为整数int
int i = Integer.parseInt(str);
2. 如何将字符串String转化为Integer
Integer integer=Integer.valueOf(i)
3. 如何将整数 int 转换成字串 String?
String s = String.valueOf(i); 

 String s = Integer.toString(i);

 String s = “” + i;


三. Leetcode&&Nowcoder实战
1. leetcode 剑指offer 38
输入一个字符串,打印出该字符串中字符的所有排列。
你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。
输入:s = "abc"
输出:["abc","acb","bac","bca","cab","cba"]
输入:
"aab"
输出:
["ab","ba"]
预期结果:
["aba","aab","baa"]
元素是可以重复的,不必进行过滤。

class Solution {
ArrayList<String> list = new ArrayList<>();
int[] used;
public String[] permutation(String s) {
used = new int[s.length()];
char[] c = s.toCharArray();
Arrays.sort(c);
String str = "";
for(char tmp:c) str += tmp;
dfs(str,"");
String[] strarr = new String[list.size()];
for(int i = 0; i < list.size(); i++){
strarr[i] = list.get(i);
}
return strarr;
}
public void dfs(String str, String temp){
if(temp.length() == str.length()){
list.add(temp);
return;
}
for(int i = 0; i < str.length(); i++){
if(used[i] == 1 || (i > 0 && str.charAt(i) == str.charAt(i-1)) && used[i-1] == 1 ) continue;
String v1 = str.substring(i,i+1);
temp += v1;
used[i] = 1;
dfs(str,temp);
temp = temp.substring(0,temp.length()-1);
used[i] = 0;
}
}
}

本题小结:(1)由Arrays.toString的字符串会多出来,【和】,奇奇怪怪不要用,直接拼接

2. NowCoder NC89 字符串变形
对于一个长度为 n 字符串,我们需要对它做一些变形。
首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。
比如"Hello World"变形后就变成了"wORLD hELLO"。
输入:
"This is a sample",16
复制
返回值:
"SAMPLE A IS tHIS"

import java.util.*;

public class Solution {
public String trans(String s, int n) {
// write code here
String[] str = s.split(" ");
String res = "";
int diff = 97-65;
for(int i = str.length-1; i>= 0; i--){
String temp = str[i];
for(int j = 0; j < temp.length(); j++){
char c = temp.charAt(j);
if(c < 97){
c = (char)(c+diff);
}
else{
c = (char)(c-diff);
}
res += c;
}
res += " ";
}

return res.substring(0,res.length()-1);
}
}

超时了

import java.util.*;

public class Solution {
public String trans(String s, int n) {
// write code here
String[] str = s.split(" ");
StringBuilder res=new StringBuilder();
int diff = 97-65;
for(int i = str.length-1; i>= 0; i--){
String temp = str[i];
for(int j = 0; j < temp.length(); j++){
char c = temp.charAt(j);
if(c < 97){
c = (char)(c+diff);
}
else{
c = (char)(c-diff);
}
res.append(c);
}
res.append(" ");
}
return res.substring(0,res.length()-1);
}
}

又有换行的问题

import java.util.*;

public class Solution {
public String trans(String s, int n) {
// write code here
String[] str = s.split(" ",-1);
StringBuilder res=new StringBuilder();
int diff = 97-65;
for(int i = str.length-1; i>= 0; i--){
String temp = str[i];

for(int j = 0; j < temp.length(); j++){
char c = temp.charAt(j);
if(c < 97){
c = (char)(c+diff);
}
else{
c = (char)(c-diff);
}
res.append(c);
}
res.append(" ");
}
return String.valueOf(res.substring(0,res.length()-1));
}
}


本题小结:

(1)用StringBuilder
(2)用s.split(" ",-1)排除干扰

3. leetcode387. 字符串中的第一个唯一字符
给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。
输入: s = "loveleetcode"
输出: 2

class Solution {
public int firstUniqChar(String s) {
int[] num = new int[26];
for(int i = 0; i < s.length(); i++){
num[s.charAt(i) - 'a']++;
}
char c = 'A';
ArrayList<Character> list = new ArrayList<>();
for(int i = 0; i < num.length; i++){
if(num[i] == 1){
c = (char)(i + 97);
list.add(c);
}
}
for(int i = 0; i < s.length(); i++){
if(list.contains(s.charAt(i))){
return i;
}
}
return -1;
}
}

简化,第一种脑回路不好 

class Solution {
public int firstUniqChar(String s) {
int[] num = new int[26];
for(int i = 0; i < s.length(); i++){
num[s.charAt(i) - 'a']++;
}
for(int i = 0; i < s.length(); i++){
if(num[s.charAt(i)-'a']==1){
return i;
}
}
return -1;
}
}

4. leetcode1160 拼写单词
给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。
注意:每次拼写(指拼写词汇表中的一个单词)时,chars 中的每个字母都只能用一次。
返回词汇表 words 中你掌握的所有单词的 长度之和。
输入:words = ["cat","bt","hat","tree"], chars = "atach"
输出:6
解释:
可以形成字符串 "cat" 和 "hat",所以答案是 3 + 3 = 6。

class Solution {
public int countCharacters(String[] words, String chars) {
int[] arr1 = new int[26];
int sum = 0;
for(int i = 0; i < chars.length(); i++){
arr1[chars.charAt(i)-'a']++;
}
for(int i = 0; i < words.length; i++){
String s = words[i];
int[] arr2 = new int[26];
int temp = s.length();
for(int j = 0; j < s.length(); j++){
arr2[s.charAt(j) - 'a']++;
if(arr2[s.charAt(j) - 'a'] > arr1[s.charAt(j)-'a']){
temp = 0;
break;
}
}
sum += temp;
}
return sum;
}
}

本题小结:(1)是words的每一个都要比较,每一个互不影响

5. leetcode43 字符串相乘
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
输入: num1 = "2", num2 = "3"
输出: "6"

class Solution {
public String multiply(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
int[] res = new int[num1.length() + num2.length()];
for (int i = num1.length() - 1; i >= 0; i--) {
int n1 = num1.charAt(i) - '0';
for (int j = num2.length() - 1; j >= 0; j--) {
int n2 = num2.charAt(j) - '0';
int sum = (res[i + j + 1] + n1 * n2);
res[i + j + 1] = sum % 10;
res[i + j] += sum / 10;
}
}

StringBuilder result = new StringBuilder();
for (int i = 0; i < res.length; i++) {
if (i == 0 && res[i] == 0) continue;
result.append(res[i]);
}
return result.toString();
}
}
C 0条回复 评论

帖子还没人回复快来抢沙发