2.字符串

一.重新排列字符串
1.题目描述:
给你一个字符串 s 和一个 长度相同 的整数数组 indices 。
请你重新排列字符串 s ,其中第 i 个字符需要移动到 indices[i] 指示的位置。
返回重新排列后的字符串。

2.示例:
图片说明

3.解:
(1)我的答案:

class Solution {
    public String restoreString(String s, int[] indices) {
        char[] result= new char[s.length()];
        for(int i=0;i<s.length();i++){
            result[indices[i]] = s.charAt(i);
        }
        return new String(result);
    }
}

4.总结:

二.左旋转字符串
1.题目描述:
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

2.示例:
输入: s = "abcdefg", k = 2
输出: "cdefgab"
1 <= k < s.length <= 10000

3.解:
(1)我的答案:

class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] a = s.toCharArray();
        char[] b = new char[a.length];
        for (int i = 0; i <a.length-n;i++){
            b[i] = a[i+2];
        }
        for (int j=a.length-n;j<a.length;j++){
            b[j] = a[j-(a.length-n)];
        }
        return String.valueOf(b) ;
    }
}

(2)网友答案:
1.

class Solution {
    public String reverseLeftWords(String s, int n) {
        return s.substring(n) + s.substring(0, n);
    }
}

2.

class Solution {
    public String reverseLeftWords(String s, int n) {
        String re = "";
        for(int i = n; i < s.length(); i++) re += s.charAt(i);
        for(int i = 0; i < n; i++) re += s.charAt(i);
        return re;
    }
}

3.

class Solution {
    public String reverseLeftWords(String s, int n) {
        StringBuilder stringBuilder1 = new StringBuilder(s.substring(0,n));
        StringBuilder stringBuilder2 = new StringBuilder(s.substring(n));
        StringBuilder stringBuilder3 = new StringBuilder(stringBuilder1.reverse().toString()+stringBuilder2.reverse().toString());
        stringBuilder3.reverse();
        return stringBuilder3.toString() ;
    }
}

4.总结:
关于字符串的题目,一定是针对字符串做处理的,字符产一定是要被改变的。那么一定会引入将字符串看成字符数组的概念。那么怎么实现这种概念呢,有四种方法:
(1)真的将字符串变成数组,然后再变回字符串。这涉及到两个方法:字符串对象.toCharArray() ,String.valueOf(字符数组对象)
(2)直接将字符串看成数组,并不真的转成字符数组,而是需要哪个字符时,就根据索引提取出字符串中对应位置的字符,这涉及到一个方法:字符串对象.charAt(索引)和一个字符串拼接操作:+ 。这个+可以拼接字符和字符,字符串和字符以及字符串和字符串。另外,某些时候需要先定义一个空字符串,可以这样写:String a = "";
(3)某些时候并不直接需要某个字符,那么就可以使用方法:字符串对象.subString(起始位置,结束位置)/(起始位置),来截取一段字符串
(4)可以将String对象转为StringBuilder /StringBuffer对象,调用reverse()方法,处理完成后再调用StringBuilder /StringBuffer对象的toString()方法。

java中String、StringBuffer和StringBuilder的区别:
(1)三者共同之处:都是final类,不允许被继承,主要是从性能和安全性上考虑的,因为这几个类都是经常被使用着,且考虑到防止其中的参数被参数修改影响到其他的应用。
(2)不同之处:
StringBuffer是线程安全,可以不需要额外的同步用于多线程中;
StringBuilder是非同步,运行于多线程中就需要使用着单独同步处理,但是速度就比StringBuffer快多了;
StringBuffer与StringBuilder的对象创建之后是可以改的,可以通过append、indert进行字符串的操作。而String对象一旦创建之后该对象是不可更改的:String a="i";a=a+"love";这并不是真的改变了变量a,而是重新创建了一个a对象,赋值为"i love",然后把旧的a对象回收。所以String对象在这三者的速度中是最慢的。因为需要进行大量的回收和创建对象操作。StringBuilder是速度最快的。当然String a = "i"+"love"这种做法并不属于上面说的情况,因为这是直接将两个String对象拼接起来后赋值给a的,a只创建了一次。
String实现了三个接口:Serializable、Comparable<string>、CarSequence。而StringBuilder只实现了两个接口Serializable、CharSequence,相比之下String的实例可以通过compareTo方法进行比较,其他两个不可以。
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。</string>

java中String、StringBuffer和StringBuilder三者相互转化:
String转其他两个:构造方法和.append()
其他两个转String:构造方法和.toString()但是注意toString方法并不是把值赋值给String对象了,而是执行:getClass().getName()+"@"+Integer.toHexString(hashCode());将Stringbuffer/StringBuilder对象的哈希值的16进制赋值给String对象,所以要想获取真正的值,还是用构造方法保险。

三.反转字符串
1.题目描述:
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

2.示例:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]

3.解:
(1)我的答案:

class Solution {
    public void reverseString(char[] s) {
        String a = new String(s);
        StringBuilder stringBuilder = new StringBuilder(a);
        stringBuilder.reverse();
        String b = stringBuilder.toString();
        for (int i=0;i<s.length;i++){
            s[i]=b.charAt(i);
        }
    }
}

(2)网友答案:
1.

class Solution {
    public void reverseString(char[] s) {
        int len=s.length-1;
        int left=0,right=len;
        while(left<right){
            char tmp=s[left];
            s[left]=s[right];
            s[right]=tmp;
            left++;
            right--;
        }
    }
}

4.总结:
网友的答案是一种常见的数组排序方法,同时从前和从后遍历数组,交换值,直到到达数组的中间元素。

四.把字符串转换成整数
1.题目描述:
写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0。

说明:
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

2.示例:
输入: "42"
输出: 42
示例 2:

输入: " -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。

输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。因此无法执行有效的转换。

3.解:
(1)我的答案:

class Solution {
    public int strToInt(String str) {
        str = str.trim();
        StringBuilder stringBuilder = new StringBuilder(str);
        if (stringBuilder.length() == 0) return 0;
        if (stringBuilder.charAt(0) != '-' && stringBuilder.charAt(0) != '+' && !Character.isDigit(stringBuilder.charAt(0)))
            return 0;
        int leng = stringBuilder.length();
        int index;
        if (stringBuilder.charAt(0) == '-' || stringBuilder.charAt(0) == '+') {
            if (stringBuilder.length() == 1) return 0;
            else if (!Character.isDigit(stringBuilder.charAt(1))) return 0;
            index = 2;
            while (index < leng) {
                if (Character.isDigit(stringBuilder.charAt(index))) index++;
                else {
                    stringBuilder.delete(index, leng);
                    break;
                }
            }
        }
        if (Character.isDigit(stringBuilder.charAt(0))) {
            index = 0;
            while (index < leng) {
                if (Character.isDigit(stringBuilder.charAt(index))) index++;
                else {
                    stringBuilder.delete(index, leng);
                    break;
                }
            }
        }
        Double result = Double.parseDouble(stringBuilder.toString());
        if (result > Integer.MAX_VALUE) return Integer.MAX_VALUE;
        else if (result < Integer.MIN_VALUE) return Integer.MIN_VALUE;
        return  result.intValue();
    }
}

4.总结
这题不太好,做出来就行了。注意用Double存储结果,然后再判断越界与否,最后转成int输出。其他人有用字符数组的,我没有用,习惯用StringBuilder了。

五.单词距离
1.题目描述:
有个内含单词的超大文本文件,给定任意两个单词,找出在这个文件中这两个单词的最短距离(相隔单词数)。如果寻找过程在这个文件中会重复多次,而每次寻找的单词不同,你能对此优化吗?

2.示例:
输入:words = ["I","am","a","student","from","a","university","in","a","city"], word1 = "a", word2 = "student"
输出:1
words.length <= 100000

3.解:
(1)我的答案:

class Solution {
    public int findClosest(String[] words, String word1, String word2) {
        int indexA = -1;
        int indexB = -1;
        int res = Integer.MAX_VALUE;
        for (int i = 0; i < words.length; i++) {
            if (words[i].equals(word1)) {
                indexA = i;
                if (indexB != -1) res = Math.min(res, Math.abs(indexA - indexB));
            }
            if (words[i].equals(word2)) {
                indexB = i;
                if (indexA != -1) res = Math.min(res, Math.abs(indexA - indexB));
            }
        }
        return res;
    }
}

4.总结
双指针做法

全部评论

相关推荐

代码飞升:别用口语,后端就写后端,前端就写前端,最后别光后悔
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务