算法题-字符串相关

判断字符串是否是回文,比如“level”或者“noon"

    public static void main(String[] args) throws Exception {
        String s = "";
        int len = s.length();
        int last =len/2;
        for(int i=0;i<last; i++){
            if(s.charAt(i)!= s.charAt(len-i-1)){
                System.out.println(false);
            }
        }
        System.out.println(true);
    }
def test(nums):
   n = len(nums)
   middle = n//2
   for i in range(0, middle):
       if nums[i] != nums[len(nums)-i-1]:
           return False
   return True

反转字符串

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

解法1:递归

def reverseString(s, left, right):
    if left >= right:
        return
    s[left], s[right] = s[right], s[left]
    reverseString(s, left+1, right-1)
alist = ["h","e","l","l","o"]
reverseString(alist, 0, len(alist)-1)
print(alist)

方法2:双指针法:

    public static void main(String[] args) throws Exception {
        String s = "asd";
        char[] c = s.toCharArray();
        int left = 0;
        int right = c.length-1;
        while(left<right){
            char temp = c[left];
            c[left] = c[right];
            c[right] = temp;
            left++;
            right--;
        }
        System.out.println(String.valueOf(c));
    }
def reverseString(s):
    left = 0
    right = len(s) - 1
    while(left < right):
        s[left], s[right] = s[right], s[left]
        left += 1
        right -= 1
alist = ["h","e","l"]
reverseString(alist)
print(alist)

无重复字符的最长子串

题目:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

public static void main(String[] args) throws Exception {
        String s = "1323";
        // 哈希集合,记录每个字符是否出现过
        Set<Character> occ = new HashSet<Character>();
        int n = s.length();
        int rk = 0, ans = 0, lk = 0;
        while (lk <= rk && rk < n) {
            if (!occ.contains(s.charAt(rk))) {
                // 不断地移动右指针
                occ.add(s.charAt(rk));
                ++rk;
            } else {
                ans = Math.max(ans, occ.size());
                if (lk != 0) {
                    // 左指针向右移动一格,移除一个字符
                    occ.remove(s.charAt(lk - 1));
                }
                lk++;
            }
            if (rk == n) {
                ans = Math.max(ans, occ.size());
            }
        }
        System.out.println(ans);
    }
        public static Integer getLen(int[] nums) {
            if (nums.length == 1) {
                return 1;
            }
            int ans = 1;
            int len = nums.length;
            for (int i = 0; i < len; i++) {
                Set<Integer> set = new HashSet<>();
                for (int j = i; j < len; j++) {
                    if (!set.add(nums[j])) {
                        ans = Math.max(set.size(), ans);
                        break;
                    }
                    if (j == len - 1) {
                        ans = Math.max(set.size(), ans);
                    }
                }
            }
            return ans;
        }
def lengthOfLongestSubString(s):
    n = len(s)
    ans = 0
    # 定义空字典,记录字符与索引的映射关系
    m = {}
    l = 0
    # 遍历右指针
    for r in range(n):
        if s[r] in m.keys():
            # 如果出现重复字符,左指针直接跳过重复元素之前的字符
            l = max(m[s[r]], l)
        # 取当前字符串长度和原先记录的子字符串长度最大值
        ans = max(ans, r-l+1)
        # 定义字符到索引的映射,即某个字符在字符串中出现的最大位置
        m[s[r]] = r+1
        r += 1
    print(ans)
    return ans

lengthOfLongestSubString("abacddtyghkja")

Fizz Buzz

写一个程序,输出从 1 到 n 数字的字符串表示。

  1. 如果 n 是3的倍数,输出“Fizz”;
  2. 如果 n 是5的倍数,输出“Buzz”;
    3.如果 n 同时是3和5的倍数,输出 “FizzBuzz”。
    方法1:模拟法
def fizzBuzz(n):
    ans = []
    for num in range(1, n+1):
        divisible_by_3 = (num % 3 == 0)
        divisible_by_5 = (num % 5 == 0)

        if divisible_by_3 and divisible_by_5:
            ans.append('FizzBuzz')
        elif divisible_by_3:
            ans.append('Fizz')
        elif divisible_by_5:
            ans.append('Buzz')
        else:
            ans.append(str(num))

    return ans

m = fizzBuzz(16)
print(m)

方法2:字符串连接

def fizzBuzz(n):
    ans = []
    for num in range(1, n + 1):
        divisible_by_3 = (num % 3 == 0)
        divisible_by_5 = (num % 5 == 0)
        num_ans_str = ""
        if divisible_by_3:
            num_ans_str += 'Fizz'
        if divisible_by_5:
            num_ans_str += 'Buzz'
        if not num_ans_str:
            num_ans_str = str(n)
        ans.append(num_ans_str)
    return ans

方法3:用散列表

  public static void main(String[] args) throws Exception {
        String ans = "";
        int n=3;
        Map<Integer, String> map = new HashMap<>();
        map.put(3, "Fizz");
        map.put(5, "Buzz");
        for(int i=n; i>0;i--){
            if(i%3==0 && i%5==0){
                ans += "FizzBuzz";
            }else if(i%3==0){
                ans += "Fizz";
            }else if(i%5==0){
                ans += "Buzz";
            }else{
                ans += String.valueOf(i);
            }
        }
        System.out.println(ans);
    }
def fizzBuzz(n):
    ans = []
    fizz_buzz_dict = {3: "Fizz", 5: 'Buzz'}
    for num in range(1, n+1):
        num_ans_str = ""
        for key in fizz_buzz_dict.keys():
            if num % key == 0:
                num_ans_str += fizz_buzz_dict[key]
        if not num_ans_str:
            num_ans_str = str(num)
        ans.append(num_ans_str)
    return ans

罗马数字转整数

def romanToInt(s):
    sum = 0
    hashmap = {'I':1,'V':5,'X':10,'L':50,'C':100,
               'D':500,'M':1000}
    pre_num = hashmap[s[0]]
    for i in range(1, len(s)):
        num = hashmap[s[i]]
        if pre_num < num:
            sum -= pre_num
        else:
            sum += pre_num
        pre_num = num
    sum += pre_num
    return sum


s = "LVIII"
print(romanToInt(s))

有效的字母异位词

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

def isAnagram(s, t):
    if len(s) != len(t):
        return False
    m = "".join(sorted(list(s)))
    n = "".join(sorted(list(t)))
    print(m)
    print(n)
    return m == n
s = 'fds'
t = 'sdf'
m = isAnagram(s, t)
print(m)

方法2:哈希

import collections
def isAnagram(s ,t):
    if s == t :
        return True
    if len(s) != len(t):
        return False
    num_s = collections.Counter(s)
    num_t = collections.Counter(t)
    return num_s == num_t
s = 'wert'
t = 'werr'
print(isAnagram(s ,t))

快乐数

编写一个算法来判断一个数是不是“快乐数”。
一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。

    public static void main(String[] args) throws Exception {
        int nums = 19;
        Set<Integer> set = new HashSet<>();
        while (nums != 1 && !set.contains(nums)) {
            set.add(nums);
            nums = getNums(nums);
        }
        System.out.println(nums == 1);
    }

    private static int getNums(int nums) {
        int sum = 0;
        while (nums != 0) {
            int d = nums % 10;
            sum += d * d;
            nums = nums / 10;
        }
        return sum;
    }
def is_happy(n):
    issam = [n]
    while n != 1:
        a = list(str(n))
        n = 0
        for i in a :
            n += pow(int(i), 2)
        issam.append(n)
        if len(issam) != len(set(issam)):
            return False
    return True

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

使用哈希表存储索引, 重复元素下角标为-1

    public static void main(String[] args) throws Exception {
        String s = "collections";
        Map<Character, Integer> position = new HashMap<>();
        int n = s.length();
        for (int i = 0; i < n; i++) {
            char ch = s.charAt(i);
            if (position.containsKey(ch)) {
                position.put(ch, -1);
            } else {
                position.put(ch, i);
            }
        }
        int first = n;
        for (Map.Entry<Character, Integer> entry : position.entrySet()) {
            int pos = entry.getValue();
            if (pos != -1 && pos < first) {
                first = pos;
            }
        }
        if (first == n) {
            first = -1;
        }
        System.out.println(first);
    }

字符串中的第一个重复字符

    public static void main(String[] args) throws Exception {
        String s = "collections";
        Set<Character> set = new HashSet<>();
        for(int i=0; i<s.length(); i++){
            char m = s.charAt(i);
            if(!set.add(m)){
                System.out.println(m);
                break;
            }
        }
        System.out.println("");
    }

阶乘后的零

给定一个整数 n,返回 n! 结果尾数中零的数量。
数学题 2*5 就有一个零,2的个数大于5的个数,只需要找5的个数。25 = 1x5x5 125 = 1x5x5x5

def trailingAeroes(n):
    count = 0
    while n>0:
        count += n//5
        n = n//5
    return count

print(trailingAeroes(5))

实现 strStr()

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

暴力遍历

 public static void main(String[] args) throws Exception {
        String s = "collect";
        String m = "ect";
        int sl = s.length();
        int ml = m.length();
        for (int i = 0; i <= sl - ml; i++) {
            boolean flag = true;
            for (int j = 0; j < ml; j++) {
                if (s.charAt(i + j) != m.charAt(j)) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                System.out.println(i);
                break;
            }
        }
    }

方法1:

haystack = "hello"
needle = "so"
m = -1
try:
    m = haystack.index(needle)
except:
    pass
print(m)

方法2:滑窗

def strStr(haystack, needle):
    l, n = len(needle), len(haystack)
    for start in range(n-l+1):
        if haystack[start: start+l] == needle:
            return start
    return -1
    public static void main(String[] args) throws Exception {
        String s = "collect";
        String m = "ect";
        int sl = s.length();
        int ml = m.length();
        for (int i = 0; i <= sl - ml; i++) {
            String q = s.substring(i,i+ml);
            if(q.equals(m)){
                System.out.println(i);
            }
        }
    }

x的平方根

def my_sqrt(x):
    if x<2:
        return x
    left, right = 2, x//2
    while left <= right:
        pivot = left + (right - left)//2
        num = pivot * pivot
        if num > x:
            right = pivot - 1
        elif num < x:
            left = pivot + 1
        else:
            return pivot
    return right

有效的括号

    public static void main(String[] args) throws Exception {
        String s = "{[]}";
        int len = s.length();
        if (len % 2 == 1) {
            System.out.println(false);
            return;
        }
        Map<Character, Character> map = new HashMap<>();
        map.put(']', '[');
        map.put(')', '(');
        map.put('}', '{');
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (map.containsKey(c)) {
                if (stack.isEmpty() || stack.peek() != map.get(c)) {
                    System.out.println(false);
                    return;
                }
                stack.pop();
            } else {
                stack.add(c);
            }
        }
        System.out.println(stack.isEmpty());
    }

反转字符串中的元音字母

给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括 ‘a’、‘e’、‘i’、‘o’、‘u’,且可能以大小写两种形式出现。

    public static void main(String[] args) throws Exception {
        String s = "sefro";
        char[] arr = s.toCharArray();
        int n = s.length();
        int i = 0, j = n - 1;
        while (i < j) {
            while (i < n && !isVowel(s.charAt(i))) {
                ++i;
            }
            while (j > 0 && !isVowel(s.charAt(j))) {
                --j;
            }
            if (i < j) {
                char temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
                i++;
                j--;
            }
        }
        System.out.println(String.valueOf(arr));
    }

    public static boolean isVowel(char ch) {
        return "aeiouAEIOU".indexOf(ch) >= 0;
    }

最长回文子串

    public static void main(String[] args) throws Exception {
        String s = "121";
        if (s == null || s.length() < 1) {
            return;
        }
        int start = 0;
        int end = 0;
        for (int i = 0; i < s.length(); i++) {
            int len1 = expandAroundCenter(s, i, i);
            int len2 = expandAroundCenter(s, i, i + 1);
            int len = Math.max(len1, len2);
            if (len > end - start) {
                start = i - (len - 1) / 2;
                end = i + len / 2;
            }
        }
        System.out.println(s.substring(start, end + 1));
    }

    public static int expandAroundCenter(String s, int left, int right) {
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
        }
        return right - left - 1;
    }

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

    public static void main(String[] args) throws Exception {
        String s = "cbaebabacd";
        String p = "abc";
        int m = s.length();
        int n = p.length();
        List<Integer> list = new ArrayList<>();
        if (m < n) {
            return;
        }
        for (int i = 0; i < m - n + 1; i++) {
            Set<Character> set = new HashSet<>();
            for (int j = i; j < i + n; j++) {
                char c = s.charAt(j);
                if (!p.contains(String.valueOf(c)) || !set.add(c)) {
                    break;
                }
                if (j == i + n - 1) {
                    list.add(i);
                }
            }
        }
        list.stream().forEach(item -> System.out.println(item));
    }

回文子串

public class AAA {

    public static void main(String[] args) throws Exception {
        String s = "abc";
        int m = s.length();
        int len = 0;
        for (int i = 0; i < m; i++) {
            len = len + expandAroundCenter(s, i, i);
            len = len + expandAroundCenter(s, i, i + 1);
        }
        System.out.println(len);
    }

    public static int expandAroundCenter(String s, int left, int right) {
        int nums = 0;
        while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
            left--;
            right++;
            nums++;
        }
        return nums;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值