Loading

剑指offer刷题

JZ3 数组中重复的数:

unordered_map与桶并不是很难想。有趣的是题解里的原地踏步法

桶和unordered_map的话都需要额外的O(n)的空间去找是否有重复的值,但是原地踏步法的是用了数组的值只在0-n之间的这个性质,在原数组上进行操作

其主要思想就是,把当前位置上的值放到对应的位置上
因为值在0-n-1之间,数组长度为n,那么意味着每个值都会有其对应在数组中的位置(0在0位置,1在1位置)。
代码如下:

int duplicate(vector<int>& numbers) {
    for (int i = 0; i < numbers.size(); ++ i) {
      if (i != numbers[i]) {
        if (numbers[i] == numbers[numbers[i]]) {
          return numbers[i];
      }
      swap(numbers[i], numbers[numbers[i]]);
      i --;
      }
    }
    return -1;
}

JZ4 二维数组中的查找:

这道题也十分有趣,一开始想用二分套二分的,但是发现了其实这个不满足二分套二分的性质,也就是假设给你一个target,你当前位置是(posn, posm),并且array(posn, posm)是大于target,那么现在有两个选择,要么往上去找,要么往左去找,但是你无法确定是上还是左,因为上面和左边都是小于array(posn, posm)。
看了题解,发现解法十分巧妙,利用了数组类似二叉搜索树的性质,先从右上角出发,如果target大于当前的话,就当前行 ++, 小于就当前列 --。等于就直接返回。
妙哉!
代码如下:

bool Find(int target, vector<vector<int> > array) {
        if (array.size() == 0) return false;
        int n = array.size();
        int m = array[0].size();
        int curn = 0;
        int curm = m-1;
        while (curn < n && curm >= 0) {
            if (array[curn][curm] == target) return true;
            else if (array[curn][curm] > target) {
                -- curm;
            }
            else {
                ++ curn;
            }
        }
        return false;
    }

JZ5 替换空格 :

这道题有点小笨,就直接新开个string按照规则模拟就好了。不放代码了。

JZ6 从尾到头打印链表:

这道题一看我就觉得用递归写,但是居然只超过了百分之一的人。
之后换成顺序遍历 + reverse 也是很慢。
之后又换成了栈,结果还是很慢。
点开了榜一大哥的代码,哦~,原来是vector的push_back太慢了

先预留空间就超快了。

没啥好放代码的。

posted @ 2022-02-20 20:02  ViKyanite  阅读(41)  评论(0编辑  收藏  举报