美文网首页
First week can't solve.

First week can't solve.

作者: Jiawei_84a5 | 来源:发表于2019-05-19 21:37 被阅读0次

    螺旋数组

    这道题让我们搓一个螺旋丸,将一个矩阵按照螺旋顺序打印出来,我们只能一条边一条边的打印,首先我们要从给定的mxn的矩阵中算出按螺旋顺序有几个环,注意最终间的环可以是一个数字,也可以是一行或者一列。环数的计算公式是 min(m, n) / 2,知道了环数,我们可以对每个环的边按顺序打印,比如对于题目中给的那个例子,个边生成的顺序是 1,2,3,6,9,8,7,4,5

    1 2 3

    4 5 6

    7 8 9

    我们定义p,q为当前环的高度和宽度,当p或者q为1时,表示最后一个环只有一行或者一列,可以跳出循环。此题的难点在于下标的转换,如何正确的转换下标是解此题的关键,我们可以对照着上面的3x3的例子来完成下标的填写,代码如下:

    class Solution {
    public:
        vector<int> spiralOrder(vector<vector<int> > &matrix) {
            if (matrix.empty() || matrix[0].empty()) return {};
            int m = matrix.size(), n = matrix[0].size();
            vector<int> res;
            int c = m > n ? (n + 1) / 2 : (m + 1) / 2;
            int p = m, q = n;
            for (int i = 0; i < c; ++i, p -= 2, q -= 2) {
                for (int col = i; col < i + q; ++col) 
                    res.push_back(matrix[i][col]);
                for (int row = i + 1; row < i + p; ++row)
                    res.push_back(matrix[row][i + q - 1]);
                if (p == 1 || q == 1) break;
                for (int col = i + q - 2; col >= i; --col)
                    res.push_back(matrix[i + p - 1][col]);
                for (int row = i + p - 2; row > i; --row) 
                    res.push_back(matrix[row][i]);
            }
            return res;
        }
    }
    

    二进制求和

    根据二进制的相加规则,当前位相加再%2则为结果,进位则/2。

    可以先建立一个StringBuilder类型的result,从后往前,将每一位相加,结果加入result,最后反转输出。

    或者可以如此理解:用int变量sum记录a和b对应位置字符的和,然后sum%2就是当前位置字符的int形式,并将其添加到StringBuilder中.是否有进位可以通过sum/2判断,并可以将carry作为下一次sum的初始值

    网上看到最简单的方法.
    用了两个指针分别指向a和b的末尾,然后每次取出一个字符,转为数字,若无法取出字符则按0处理,然后定义进位carry,初始化为0,将三者加起来,对2取余即为当前位的数字,对2取商即为当前进位的值,记得最后还要判断下carry,如果为1的话,要在结果最前面加上一个1。

    class Solution {
    public:
        string addBinary(string a, string b) {
            string res = "";
            int m = a.size() - 1, n = b.size() - 1, carry = 0;
            while (m >= 0 || n >= 0) {
                int p = m >= 0 ? a[m--] - '0' : 0;
                int q = n >= 0 ? b[n--] - '0' : 0;
                int sum = p + q + carry;
                res = to_string(sum % 2) + res;
                carry = sum / 2;
            }
            return carry == 1 ? "1" + res : res;
        }
    }
    

    长度最小子数组

    双指针的核心思想就是要维护两个指针:一个快指针和一个慢指针,并确定两个指针的移动策略。有了这个思路,再想一下这个题目里面双指针的移动策略应该怎么确定。
    首先可以将元素尽量多地累计起来,让它们的和超过s,再按数组的索引,从小到大去掉一些元素,使元素和逼近s,并保持元素和大于等于s。这个时候,通过一左一右两个指针(索引)就可以计算出最小连续数组的长度。

    public int minSubArrayLen(int s, int[] nums)
    {
        int len = nums.length;
        int ans = Integer.MAX_VALUE;
        int left = 0;
        int sum = 0;
        for (int i = 0; i < len; i++)
        {
            sum += nums[i]; // 把前i个元素累加起来
            while (sum >= s)
            {
                ans = Math.min(ans, i - left + 1);
                sum -= nums[left++]; // 依次剔除元素,使sum尽量接近s
            }
        }
        return (ans != Integer.MAX_VALUE)? ans : 0;
    }
    

    相关文章

      网友评论

          本文标题:First week can't solve.

          本文链接:https://www.haomeiwen.com/subject/mgoqzqtx.html