算法Ⅰ(字符串篇)

344、反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

//找规律
void reverseString(vector<char>& s) {
  int len = s.size();
  for (int i = 0; i < len / 2; i++) {
    swap(s[i], s[len - i - 1]);
  }
}

//双指针
void reverseString(vector<char>& s) {
  int len = s.size();
  int i = 0, j = len - 1;
  while (i < j) {
    swap(s[i], s[j]);
    i++, j--;
  }
}

7、整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)

int reverse(int x) {
  if (x == 0) {
    return 0;
  }
  int remain, sum = 0;
  while (x) {
    remain = x % 10;
    if (sum > INT32_MAX / 10 || sum < INT_MIN / 10) return 0;
    sum = sum * 10 + remain;
    x /= 10;
  }
  return sum;
}

//转成字符串try判断是否溢出
int reverse(int x) {
  string s = to_string(x);           //变成字符串
  std::reverse(s.begin(), s.end());  //翻转字符串
  int ans = 0;
  try {
    ans = stoi(s);          //变回数字
    if (x < 0) ans = -ans;  // x是负数,加上负号
  } catch (exception ex) {
  }  //溢出,啥也不做,返回零
  return ans;
}

注意内存溢出!!!

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

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

int firstUniqChar(string s) {
  int len = s.length();
  unordered_map<char, int> mp;
  for (int i = 0; i < len; i++) {
    mp[s[i]]++;
  }
  for (int i = 0; i < len; i++) {
    if (mp[s[i]] == 1) return i;
  }
  return -1;
}

242、有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

bool isAnagram(string s, string t) {
  if (s.size() != t.size()) return false;
  unordered_map<char, int> mps;
  unordered_map<char, int> mpt;
  for (int i = 0; i < s.size(); i++) {
    mps[s[i]]++;
    mpt[t[i]]++;
  }
  for (int i = 0; i < s.size(); i++) {
    if (!mpt[s[i]])
      return false;
    else {
      if (mps[s[i]] != mpt[s[i]]) return false;
    }
  }
  return true;
}

//迭代器
bool isAnagram(string s, string t) {
  if (s.size() != t.size()) return false;
  map<char, int> mps;
  map<char, int> mpt;
  for (int i = 0; i < s.size(); i++) {
    mps[s[i]]++;
    mpt[t[i]]++;
  }
  for (auto it = mps.begin(); it != mps.end(); it++) {
    if (!mpt[it->first]) return false;
    if (mps[it->first] != mpt[it->first]) return false;
  }
  return true;
}
//先排序,依次判断
bool isAnagram(string s, string t) {
  if (s.size() != t.size()) return false;
  sort(s.begin(), s.end());
  sort(t.begin(), t.end());
  for (int i = 0; i < s.size(); i++) {
    if (s[i] != t[i]) return false;
  }
  return true;
}

bool isAnagram(string s, string t) {
  if (s.size() != t.size()) return false;
  sort(s.begin(), s.end());
  sort(t.begin(), t.end());
  if (s != t) return false;
  return true;
}

//单哈希表
bool isAnagram(string s, string t) {
  if (s.size() != t.size()) return false;
  unordered_map<char, int> mp;
  for (int i = 0; i < s.size(); i++) {
    mp[s[i]]++;
    mp[t[i]]--;
  }
  for (int i = 'a'; i <= 'z'; i++) {
    if (mp.find(i) != mp.end() && mp[i]) return false;
  }
  return true;
}

125、验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将空字符串定义为有效的回文串。

bool isPalindrome(string s) {
  int len = s.size();
  if (len == 0) return true;

  int left = 0, right = len - 1;
  while (left < right) {
    while (left < right && !isdigit(s[left]) && !isalpha(s[left])) {
      left++;
    }
    while (left < right && !isdigit(s[right]) && !isalpha(s[right])) {
      right--;
    }
    if (tolower(s[left]) != tolower(s[right])) return false;
    left++;
    right--;
  }
  return true;
}

8、字符串转换整数

int myAtoi(string s) {
  int flag = 1, ans = 0, i = 0;
  while (s[i] == ' ') i++;
  if (s[i] == '+') {
    i++;
  } else if (s[i] == '-') {
    flag = -1;
    i++;
  }

  while (i < s.size() && s[i] <= '9' && s[i] >= '0') {
    int digit = s[i] - '0';
    if (ans > INT_MAX / 10) {
      return flag > 0 ? INT_MAX : INT_MIN;
    }
    if (ans == INT_MAX / 10 && flag > 0 && digit >= INT_MAX % 10) {
      return INT_MAX;
    }
    if (ans == INT_MAX / 10 && flag < 0 && digit >= flag * (INT_MIN % 10)) {
      return INT_MIN;
    }
    ans = 10 * ans + digit;
    i += 1;
  }
  return flag * ans;
}

28、实现 strStr()

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。

//api
int strStr(string haystack, string needle) {
  if (needle.empty()) return 0;
  if (haystack.find(needle) == string::npos)
    return -1;
  else
    return haystack.find(needle);
}

//双指针检索
int strStr(string haystack, string needle) {
  if (needle.size() == 0) return 0;
  int i = 0, j = 0;
  while (i < haystack.size() && j < needle.size()) {
    if (haystack[i] == needle[j]) {
      i++;
      j++;
    } else {
      i = i - j + 1; //主串从上次匹配的下一个字符开始
      j = 0;
    }
  }
  if (j == needle.size()) return (i - j);
  return -1;
}

38、外观数列

//递归实现
string countAndSay(int n) {
  if (n == 1) return "1";
  string str = countAndSay(n - 1);
  string res;

  int len = str.size();
  int cnt = 1;
  for (int i = 0; i < len; i++) {
    if (str[i] == str[i + 1]) {
      cnt++;
    } else {
      res += cnt + '0';
      res += str[i];
      cnt = 1;
    }
  }
  return res;
}

14、最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。

string longestCommonPrefix(vector<string>& strs) {
  if (strs.size() == 0) return "";
  string ans = strs[0];
  for (int i = 1; i < strs.size(); i++) {
      //如果首次出现的位置不是第一个位置
    while (strs[i].find(ans) != 0) {
      ans = ans.substr(0, ans.size() - 1);
      if (ans == "") return ans;
    }
  }
  return ans;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

eynoZzzzc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值