字符串:反转字符串

字符串:反转字符串

题目:541. 反转字符串 II

给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

提示:

  • 该字符串只包含小写英文字母。
  • 给定字符串的长度和 k 在 [1, 10000] 范围内。
输入: s = "abcdefg", k = 2
输出: "bacdfeg"

思路

在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。

当需要固定规律一段一段去处理字符串的时候,要想想在for循环的表达式上做文章,如1006. 笨阶乘。

代码

class Solution {
    public String reverseStr(String s, int k) {
        char[] a = s.toCharArray();  //转换成char数组
        for (int start = 0; start < a.length; start += 2 * k) {
            int i = start;
            int j = Math.min(start + k - 1, a.length - 1);   //注意边界
            while (i < j) {  // 翻转从 i 到 j 的字符块
                char tmp = a[i];
                a[i++] = a[j];
                a[j--] = tmp;
            }
        }
        return new String(a);  //返回String
    }
}

题目:1006. 笨阶乘

通常,正整数 n 的阶乘是所有小于或等于 n 的正整数的乘积。例如,factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1。

相反,我们设计了一个笨阶乘 clumsy:在整数的递减序列中,我们以一个固定顺序的操作符序列来依次替换原有的乘法操作符:乘法(*),除法(/),加法(+)和减法(-)。

例如,clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1。然而,这些运算仍然使用通常的算术运算顺序:我们在任何加、减步骤之前执行所有的乘法和除法步骤,并且按从左到右处理乘法和除法步骤。

另外,我们使用的除法是地板除法(floor division),所以 10 * 9 / 8 等于 11。这保证结果是一个整数。

实现上面定义的笨函数:给定一个整数 N,它返回 N 的笨阶乘。

输入:4
输出:7
解释:7 = 4 * 3 / 2 + 1

输入:10
输出:12
解释:12 = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1

思路

思路一:在for循环的表达式上做文章

思路二:同计算波兰表达式一样,使用栈来帮助计算结果

思路三:数学解法

  • 当 N ≤4 时,可以分别单独计算「笨阶乘」
  • 当 N >4 时,可以根据 N 对 4 取模的余数进行分类讨论

代码

思路一

class Solution {
    public int clumsy(int N) {
        int ans = 0;
        for(int i=N;i>0;i = (i-4)){
            int sum = i;
            if(i != N) sum *= -1;   //除首次循环都是负
            int j = i - 1;
            int flag = 3;
            while(j>0){
                if(flag == 3){
                    sum = sum * j;
                }else if(flag == 2){
                    sum = sum/j;
                }else if(flag == 1){
                    sum = sum + j;
                    break;
                }
                flag--;
                j--;
            }
            ans +=sum;
        }
        return ans;
    }
}

思路二

class Solution {
    public int clumsy(int N) {
        // 捏出来一个栈,用于存放过程中的中间结果
        Stack<Integer> stack = new Stack<>();
        // 首先定义初次运算方式为 * [0: *, 1: /, 2: +, 3: -]
        int operation = 0;
        stack.push(N);  // 然后把第一个操作数放进来
        // 只要操作数大于 0,就一直循环下去
        while (--N > 0) {
            // 如果是乘法,就把栈顶元素拿出来和当前元素相乘再放回去
            if (operation % 4 == 0) stack.push(stack.pop() * N);
            // 如果是除法,就把栈顶元素拿出来与当前元素相除再放回去,需要注意的是运算顺序
            else if (operation % 4 == 1) stack.push(stack.pop() / N);
            // 如果是加法,那么就直接放进来这个数
            else if (operation % 4 == 2) stack.push(N);
            // 如果是减法的话,当然直接放进来它的负数
            else stack.push(-N);
            // 然后循环下一个操作
            operation = (operation + 1) % 4;
        }
        int ans = 0;
        // 把栈中的元素累加起来,就得到了最后的结果
        for (int num : stack) ans += num;
        return ans;
    }
}

思路三

class Solution {
    public int clumsy(int N) {
        if (N == 1) {
            return 1;
        } else if (N == 2) {
            return 2;
        } else if (N == 3) {
            return 6;
        } else if (N == 4) {
            return 7;
        }

        if (N % 4 == 0) {
            return N + 1;
        } else if (N % 4 <= 2) {
            return N + 2;
        } else {
            return N - 1;
        }
    }
}
posted @ 2021-03-31 19:32  当康  阅读(176)  评论(0编辑  收藏  举报