字符串基础知识和引申题目

Python 中字符串 x = 'abbc’和Java中的String x = “abbc” 是imutable的,好处是线程安全的也就是说当将其加一个字符或者减一个字符其实都是新生成了一个String,原来的String还是原来的内容
C++的话,字符串它是可变的在多线程环境

string immutable

遍历字符串

for ch in "abbc":
	print(ch)
String x = "abbc";
for (int i = 0; i < x.size(); ++i) {
	char ch = x.charAt(i);
}
for ch in x.toCharArray() {
	System.out.println(ch);
}
string s1 = "abbc";
for (int i = 0; i < s1.length(); i++) {
	count << x[i];
}
字符串比较

Java:
String x = new String(“abb”);
String y = new String(“abb”);
在Java中比较的是指针(地址),而不是比较字符串里的内容

x == y --> false // x和y是不同的变量,即不同内存上的地址,所以它指向内存中的不同地址
x.equals(y) --> true // equals判断里面的内容相同
x.equalsIgnoreCase(y) --> true // 同时忽略它的大小写

387. 字符串中的第一个唯一字符

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
示例:
s = “leetcode”
返回 0
s = “loveleetcode”
返回 2
该题目印象非常深刻,大二参考复旦大学插班生入学考试类似于转校考试,复试时面试官出这个题目,很遗憾被刷

1.暴力法brute-force: O(n^2)
i 枚举所有字符,
j 枚举i后面的所有字符: 笔记j里面有没有和i相同的,如果有相同的说明没有重复,如果没有相同的i的话,第一个找到了

2 map (hashmap哈希表实现O(1)查重复, treemap O(logN)查重复二叉树实现)

3 hash table

public int firstUniqChar(String s) {
	HashMap<Character, Integer> hm = new HashMap();
	for (int i = 0; i < s.length(); i++) {
		ha.put(s.charAt(i), hm.getOrDefault(s.charAt(i), 0) + 1);
	}
	for (int i = 0; i < s.length(); i++) {
		if (hm.get(s.charAt(i)) == 1) {
			return i;
		}
	}
	return -1;
}

8. 字符串转换整数 (atoi)

请你来实现一个 atoi 函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。接下来的转化规则如下:
如果第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字字符组合起来,形成一个有符号整数。
假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成一个整数。
该字符串在有效的整数部分之后也可能会存在多余的字符,那么这些字符可以被忽略,它们对函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换,即无法进行有效转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0 。
提示:
本题中的空白字符只包括空格字符 ’ ’ 。
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231)

public int myAtoi(String str) {
	int index = 0, sign = 1, total = 0;
	
	//1. Empty string
	if(str.length() == 0) return 0;
	
	//2. Remove Spaces
	while(str.charAt(index) == ' ' && index < str.length())
		 index ++;
		 
	//3. Handle signs
	if(str.charAt(index) == '+' || str.charAt(index) == '-'){
 		sign = str.charAt(index) == '+' ? 1 : -1;
 		index ++;
	}
	
	//4. Convert number and avoid overflow
	while(index < str.length()){
		int digit = str.charAt(index) - '0';
		if(digit < 0 || digit > 9) break;
		
		//check if total will be overflow after 10 times and add digit
		if(Integer.MAX_VALUE/10 < total ||
 		 Integer.MAX_VALUE/10 == total && Integer.MAX_VALUE %10 < digit)
			return sign == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
	     total = 10 * total + digit;
 		index ++;
	}
	return total * sign;
 }

strip函数原型
声明:s为字符串,rm为要删除的字符序列. 只能删除开头或是结尾的字符或是字符串。不能删除中间的字符或是字符串。
s.strip(rm) 删除s字符串中开头、结尾处,位于 rm删除序列的字符
s.lstrip(rm) 删除s字符串中开头处,位于 rm删除序列的字符
s.rstrip(rm) 删除s字符串中结尾处,位于 rm删除序列的字符
注意:1. 当rm为空时,默认删除空白符(包括’\n’, ‘\r’, ‘\t’, ’ ')
2.这里的rm删除序列是只要边(开头或结尾)上的字符在删除序列内,就删除掉。

class Solution(object):

	def myAtoi(self, s):

		 if len(s) == 0 : return 0
		 ls = list(s.strip())

		 sign = -1 if ls[0] == '-' else 1
		 if ls[0] in ['-','+'] : del ls[0]

 		ret, i = 0, 0
		while i < len(ls) and ls[i].isdigit() :
			 ret = ret*10 + ord(ls[i]) - ord('0')
 			 i += 1
		return max(-2**31, min(sign * ret,2**31-1))

14. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入: [“flower”,“flow”,“flight”]
输出: “fl”
示例 2:
输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。

1 暴力法:从长度最小的单词开始枚举,看这个单词是不是其他里面的前缀,然后长度减1
2 写两层嵌套循环, 将字符串对齐排在一起
“flower”
“flow”
“flight”
检查第1列是否相同,相同的话就看第2列 …,

    public static String longestCommonPrefix(String[] strs) {
        if (strs == null || strs.length == 0) return "";
        for (int i = 0; i < strs[0].length(); i++) {
            char c = strs[0].charAt(i);
            for (int j = 1; j < strs.length; j++) {
                if (i == strs[j].length() || strs[j].charAt(i) != c)
                    return strs[0].substring(0, i);
            }
        }
        return strs[0];
    }

151. 翻转字符串里的单词

给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: “the sky is blue”
输出: “blue is sky the”
示例 2:
输入: " hello world! "
输出: “world! hello”
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: “a good example”
输出: “example good a”
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明:
无空格字符构成一个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

必备知识点:

java - 在Java中将字符串拆分为整数列表
我想拆分一个字符串形式:
" 42 2152 12 3095 2"
到整数列表中,但是当我使用.split(" “)函数时,由于开头是空白,所以开头却是一个空的”“元素。
有没有办法在没有空元素的情况下拆分它?
在对数组调用split之前,请使用String.trim()函数。这将删除原始字符串之前和之后的所有空格
例如:
String original = " 42 2152 12 3095 2”;
original = original.trim();
String[] array = original.split(" “);
为了使代码更整洁,您还可以将其编写为:
String original = " 42 2152 12 3095 2”;
String[] array = original.trim().split(" ");
如果我们打印出数组:
for (String s : array) {
System.out.println(s);
}
输出为:
42
2152
12
3095
2
public static void main(String[] args) {
String[] myArray = { “Apple”, “Banana”, “Orange” };
List myList = new ArrayList(Arrays.asList(myArray));
myList.add(“Guava”);
}

// split, reverse, join
   public String reverseWords(String s) {
        // trim() 方法用于删除字符串的头尾空白符  
        // " +"指多个空格
        String[] words = s.trim().split(" +");
        // 将数组反序
        Collections.reverse(Arrays.asList(words));
        return String.join(" ", words);
    }

/*
reverse 整个string ,然后在单独reverse每个单词
the sky is blue
eulb si yks eht
blue is sky the
*/

242. 有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1:
输入: s = “anagram”, t = “nagaram”
输出: true
示例 2:
输入: s = “rat”, t = “car”
输出: false
说明:
你可以假设字符串只包含小写字母。
进阶:
如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?

要判断

438. 找到字符串中所有字母异位词

给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。
说明:
字母异位词指字母相同,但排列不同的字符串。
不考虑答案输出的顺序。
示例 1:
输入:
s: “cbaebabacd” p: “abc”
输出:
[0, 6]
解释:
起始索引等于 0 的子串是 “cba”, 它是 “abc” 的字母异位词。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的字母异位词。
示例 2:
输入:
s: “abab” p: “ab”
输出:
[0, 1, 2]
解释:
起始索引等于 0 的子串是 “ab”, 它是 “ab” 的字母异位词。
起始索引等于 1 的子串是 “ba”, 它是 “ab” 的字母异位词。
起始索引等于 2 的子串是 “ab”, 它是 “ab” 的字母异位词。

判断abc,在前一个字符串中出现过几次,因为abc本身长度是3,那么前面检测的长度
为3的就行,也就是说拥有一个长度为3的窗口,这个窗口从左边慢慢向右边滑
每次滑一步,就看窗口中的单词和abc是不是异位词,每次都是增加一个字符和减少一个字符
所以如果用map存,就可以方便的把出窗口字符减掉,进窗口字符加进来

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值