ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

字符串 & 数学 & 其它

2022-04-08 16:01:08  阅读:162  来源: 互联网

标签:其它 String int builder length 数学 字符串 new public


剑指 Offer 38. 字符串的排列:https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/

点击查看代码
// 思想:从剩余可选字符中填充指定位置,直到所有位置填充完成
// 注意String和char[]互转;ArrayList转数组均通过toArray(new T[0])完成
public class Solution {
    public String[] permutation(String s) {
        // 标记该元素是否已使用,剪枝
        boolean[] used = new boolean[s.length()];
        // 用于结果去重
        HashSet<String> resSet = new HashSet<>();
        dfs("", s, resSet, used);

        ArrayList<String> res = new ArrayList<>(resSet);
        return res.toArray(new String[0]);
    }

    private void dfs(String curStr, String s, HashSet<String> set, boolean[] used) {
        if (curStr.length() == s.length()) {
            set.add(curStr);
        }
        // 填充下一位置的元素
        for (int i = 0; i < s.length(); i++) {
            if (used[i]) {
                // 如果该元素已经使用了,则继续查找下一个未使用的元素
                continue;
            }
            used[i] = true;
            dfs(curStr + s.charAt(i), s, set, used);
            used[i] = false;
        }
    }
}

剑指 Offer 48. 最长不含重复字符的子字符串:https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/

点击查看代码
// 最长不含重复字符的子字符串:双指针 + hashmap
public class Solution {
    public static int lengthOfLongestSubstring(String s) {
        //k-v = 字符 - 字符所在位置。如果存在重复字符,更新位置到最新
        HashMap<Character, Integer> map = new HashMap<>();
        //非重复字符串长度 = r - l, l维护的是非重复区间的左边界(l, r]
        int l = -1;
        int maxLen = 0;
        for (int r = 0; r < s.length(); r++) {
            if (map.containsKey(s.charAt(r))) {
                // 更新左指针, 取max是为了避免abba这种样例场景下l的倒退
                l = Math.max(l, map.get(s.charAt(r)));
            }
            maxLen = Math.max(maxLen, r - l);
            map.put(s.charAt(r), r);
        }
        return maxLen;
    }
}
  1. 颠倒字符串中的单词:https://leetcode-cn.com/problems/reverse-words-in-a-string/
点击查看代码
// 正则表达式实现,忽略题目O(1)的空间复杂度限制
public class Solution {
    public String reverseWords(String s) {
        // 去掉空格,个数不限 "[\\s]+", 分割的字符串数组中存在""情况
        // 去掉逗号,个数不限 "[,]+", 分割的字符串数组中存在""情况
        String[] strArr = s.split("[\\s]+");
        // 题目已保证字符串种至少存在一个单词,StringBuilder非线程安全&性能更佳
        StringBuilder builder = new StringBuilder();
        int i = strArr.length - 1;
        while (i >= 0) {
            if (strArr[i].length() > 0) {
                if (builder.length() == 0) {
                    builder.append(strArr[i]);
                } else {
                    builder.append(" ").append(strArr[i]);
                }
            }
            i--;
        }

        return builder.toString();
    }
}

// 题目限制了空间复杂度为O(1):使用subString,用r和l保存单个单词的取值区间
public class Solution {
    public String reverseWords(String s) {
        StringBuilder builder = new StringBuilder();
        int r = s.length() - 1;
        while (r >= 0) {
            // r指向单次最右边的字母
            while (r >= 0 && s.charAt(r) == ' ') {
                r--;
            }
            if (r < 0) {
                break;
            }
            // l指向单次最左边的字母
            int l = r - 1;
            while (l >= 0 && s.charAt(l) != ' ') {
                l--;
            }
            if (l < 0 && s.charAt(0) == ' ') {
                break;
            }
            l++;

            // 基于l和r截取s的子串,[l, r)
            String subStr = s.substring(l, r + 1);
            if (builder.length() == 0) {
                builder.append(subStr);
            } else {
                builder.append(" ").append(subStr);
            }

            // 更新r
            r = l - 1;
        }
        return builder.toString();
    }
}

剑指 Offer 62. 圆圈中最后剩下的数字:https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/

点击查看代码
// 通用解法:使用队列模拟实现,但m很大时模拟实现会超时
public class Solution {
    public int lastRemaining(int n, int m) {
        LinkedList<Integer> queue = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            queue.add(i);
        }

        while (queue.size() > 1) {
            int i = 1;
            // 循环淘汰第m个数字
            while (i < m) {
                queue.add(queue.poll());
                i++;
            }
            queue.poll();
        }
        return queue.poll();
    }
}

// 数学推导,定义:f(n, m)表示有n个人时最后存活下来的人的编号
// 则f(n, m) = (f(n-1, m) + m) % n, 且f(1,m) = 0
public class Solution {
    public int lastRemaining(int n, int m) {
        // 最后存活下来的人的编号, n == 1
        int pos = 0;
        // 基于公式,推导初始化状态下的存活下来的人的编号n > 1
        for (int i = 2; i <= n; i++) {
            pos = (pos + m) % i;
        }
        return pos;
    }
}
  1. 用 Rand7() 实现 Rand10():https://leetcode-cn.com/problems/implement-rand10-using-rand7/
点击查看代码
// 利用rand7可产生49个随机数,基于7进制,数据取值范围是[8, 56]
// 要生成[1,10]范围随机数,每4个数对应1~10中的一个数,则需要40个数
// 因此:rand7产生的数中,我们需要的数据范围是[8,47],总共40个数
public class Solution extends SolBase {
    public int rand10() {
        // 利用rand7生成[8,47]范围中的数
        int val = 48;
        while (val > 47) {
            val = (rand7() * 7 + rand7());
        }
        // 基于val构造rand10范围的数[1,10]
        return (val - 8) / 4 + 1;
    }
}

标签:其它,String,int,builder,length,数学,字符串,new,public
来源: https://www.cnblogs.com/aizi/p/16117667.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有