PS:算法并非原创,总结的本意在于温故知新、巩固知识。侵删。
1、反转字符串
使用C++解答,代码如下:
class Solution {
public:
void reverseString(vector<char>& s) {
int n=s.size();
for(int i=0;i<n/2;i++){
swap(s[i],s[n-i-1]);
}
}
};
算法解析:
简单调换数组头尾的元素,没啥算法,想起来用swap()函数就更简单了。
2、整数反转
使用C++解答,代码如下:
class Solution {
public:
int reverse(int x) {
int result(0);
while (x!=0) {
if (result > INT_MAX / 10) {
return 0;
}
if (result < INT_MIN / 10) {
return 0;
}
result *=10;
result += x % 10;
x /= 10;
}
return result;
}
};
算法解析:
常量INT_MAX和INT_MIN分别表示最大、最小整数,定义在头文件limits.h中。
INT_MAX = 2^31-1,INT_MIN= -2^31。两个if语句用来判断结果是否溢出,如果溢出将会直接返回0;
而正常情况下,为了完成整数的反转,定义一个result作为结果变量,一开始为0,每一次循环将x的个位取出,成为result的最低位,随着循环进行,result中每一次进行*10操作,使得x的越低的位数,成为result中位数越高的位数。循环在取到x的最高位时结束。
这个题目没啥难度,大一C语言基础课就做过类似的,可能还有更好的解法,但是我暂时没发现。
3、字符串中的第一个唯一字符
使用python解答,代码如下:
class Solution:
def firstUniqChar(self, s):
"""
:type s: str
:rtype: int
"""
from collections import Counter
if s and s.count(s[0])==1:
return 0
length = len(s) + 1
s_dict = Counter(s)
num = length
for elem in s_dict:
if s_dict[elem] == 1:
elem_index = s.index(elem)
if elem_index <= num:
num = elem_index
if num == 0:
break
if num < length:
return num
else:
return -1
算法解析:
基本思想还是使用字典,字典也的确在字数统计方面有着天然优势。经过counter(s)步骤得出s_dict字典,如果字典中某个元素为1,那么我们还需要将这个下标(使用 s.index(elem)
得出)和之前得到的结果比较,num用来存储下标,最中比较得出最小的下标。
4、有效的字母异位词
使用python解答,代码如下:
class Solution:
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
dic1=collections.Counter(s)
dic2=collections.Counter(t)
return operator.eq(dic1,dic2)
算法解析:
使用字典,判断两个数生成的字典是不是相同,很直接的做法。
也可以选择先排序,然后比较,这样通过strcmp也可以实现。
5、验证回文串
使用JAVA解答,代码如下:
class Solution {
public boolean isPalindrome(String s) {
char[] cha = s.toCharArray();
int i = 0, j = cha.length - 1;
while(i < j){
if(!Character.isLetterOrDigit(cha[i]))
i++;
else if(!Character.isLetterOrDigit(cha[j]))
j--;
else
if(Character.toLowerCase(cha[i]) == Character.toLowerCase(cha[j])){
i++;
j--;
}else{
return false;
}
}
return true;
}
}
算法解析:
基本算法思想是头尾逐个字母比较。Character.isLetterOrDigit(cha[i])从名字也看得出来这个是干啥的,也就是判断一个字符是不是字母或者数字。用在此处,实现两侧遍历当遇到符号时跳过。如果字母或者数字相等且未到达中点时,继续比较,否则结束比较,得出结论。
6、字符串转换整数(atoi)
使用C++解答,代码如下:
class Solution {
public:
int myAtoi(string str) {
int i=0, n=str.size();
while(i<n&&str[i]==' ')
i++;
int sign=1;
long res=0;
if(str[i]=='-'||str[i]=='+'){
sign=(str[i++]=='-')?(-1):1;
}
while(i<n&&str[i]>='0'&&str[i]<='9'){
res=res*10+(str[i++]-'0');
if(res*sign>INT_MAX)
return INT_MAX;
if(res*sign<INT_MIN)
return INT_MIN;
}
return res*sign;
}
};
算法解析:
首先通过遍历找到第一个非空符号,然后判断数字有无正负号,通过 sign=(str[i++]==’-’)?(-1):1;这行命令,如果str[i]是‘-’,那么让sign等于-1,否则sign等于 1 。整个语句就是判断s的正负号。此后的操作将数字字符转为数字,较为简单。INT_MAX和INT_MIN在整数反转中提到过。用来控制数据的转换范围。
7、实现strStr()
使用JAVA解答,代码如下:
class Solution {
public int strStr(String haystack, String needle) {
return haystack.indexOf(needle);
}
}
算法解析:
根据题目要求,其实使用数据结构中的KMP算法也可以胜任,但比较占内存空间。此处用JAVA进行解答,emmmm,算是一个捷径吧,希望自己以后能记住这个用法。不过此处应该是通过自己的编写实现这个函数功能的。
注意此题的讨论点:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
8、外观数列
使用JAVA解答,代码如下:
class Solution {
public String countAndSay(int n) {
String str = "1";
for (int i = 2; i <= n; i++) {
StringBuilder builder = new StringBuilder();//新建一个string类用于拼接
char pre = str.charAt(0);//取第一个字符
int count = 1;//统计有几个相同的
for (int j = 1; j < str.length(); j++) {
char c = str.charAt(j);
if (c == pre) {
//后一个字符与前一个相同
count++;
}
else {
builder.append(count).append(pre);//拼接count个pre
pre = c;//前缀等于不同处
count = 1;
}
}
builder.append(count).append(pre);//拼接count个pre
str = builder.toString();//转换为string
}
return str;
}
}
算法解析:
在str中,通过循环得出每一段相同字符的长度,然后进行字符串的拼接。然后取下一段相同字符,重复操作。两个遍历中,第一层的i遍历确定最终的字符串长度,第二次的j遍历确定字符中每段都得到遍历。每一次的i遍历中,字符串长度均会发生变化。
9、最长公共前缀
使用C++解答,代码如下:
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if (strs.empty())
return "";
for (int j = 0; j < strs[0].size(); ++j) {
for (int i = 0; i < strs.size() - 1; ++i) {
if (j >= strs[i].size() || j >= strs[i + 1].size() || strs[i][j] != strs[i + 1][j]) {
return strs[i].substr(0, j);
}
}
}
return strs[0];
}
};
算法解析:
strs实际上是一个字符串组,包含多个字符串。j用来确定最长公共前缀的长度。当j大于某个字符串长度或者不再满足相等条件时,j为最终的长度,结果返回strs[i].substr(0,j),表示返回最长公共前缀。反之,j不断递增。如果遍历全部完成,说明第一个字符串全体均为最长公共前缀,返回strs[0]。