[日常刷题]leetcode+剑指offer D001

文章目录

    • 771.Jewels and Stones
      • - 1. Description
      • - 2. Solution in C++
    • 二位数组中的查找
      • - 1. 题目描述
      • - 2. c++解题方案
    • 小结
      • - 知识点

771.Jewels and Stones

- 1. Description

You’re given strings Jrepresenting the types of stones that are jewels, and S representing the stones you have. Each character in S is a type of stone you have. You want to know how many of the stones you have are also jewels.

The letters in J are guaranteed distinct, and all characters in J and S are letters. Letters are case sensitive, so "a" is considered a different type of stone from "A".

Example 1:

Input: J = "aA", S = "aAAbbbb"
Output: 3

Example 2:

Input: J = "z", S = "ZZ"
Output: 0

Note:

  • S and J will consist of letters and have length at most 50.
  • The characters inJ are distinct.

- 2. Solution in C++

关键点:

  • 效率 index vs hash

思路:

  • 一般这种题目我拿到都会考虑map去建立映射表,但是这里J串中都是字母,个数是有限的,所以也有考虑要不要直接建立一维数组去存的问题,但是发现还是map比较容易;之后又在想要不要用set去存,看set有没有in的方法去直接判断,我后来看到的是find方法,是一个一个遍历即我关键点里面提到的index问题,所以打算直接用map。
  • 这题很简单,由于J中各元素都是各不相同的,所以直接建立映射表,都不用判断是否存过。然后直接遍历S,加查表的结果即可。这里如果不在map中会自动添加一个value为0的key-value对,所以不影响结果。
  • 然后看discuss里面有人使用set中的count方法也达到了相同的效果。如果在set中有该元素则返回1,无则返0。
    [不知道具体内部怎么实现的所以这里复杂度不知道,之后看完源码补上]
  • 复杂度: O(J+S)

方法一: map

class Solution {
public:
    int numJewelsInStones(string J, string S) {
        map maps;
        for(auto ch : J){
            maps[ch] = 1;
        }
        
        size_t size = 0;
        for(char ch : S){
            size += maps[ch];
        }
        
        return size;
    }
};

方法二: set

int numJewelsInStones(string J, string S) {
        int res = 0;
        unordered_set setJ(J.begin(), J.end());
        for (char s : S) if (setJ.count(s)) res++;
        return res;
    }

二位数组中的查找

- 1. 题目描述

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

- 2. c++解题方案

关键点:

  • 二分查找的思想是两次的问题一样只是规模减半

思路:

  • 这题算是自己解题失败。最开始想的是二分查找的方法,但是两个维度一起变感觉有点复杂,而且也不能根据数组的存储规律来把其转换为一维的有序数列,所以我突发奇想。可以先判断数是否在某行,再判断是否在某列,就锁定了数的范围了,就好判断了。(我这里的锁定是锁定在了该行和该列,而不是一个矩形的范围内),可想而知,吭哧吭哧编完代码,跑过了68.7%,发现了自己的逻辑漏洞,然后开始又转回去用二分二维一起,发现会出现“震荡”的情况,此时一个小时过去了,我略带绝望地搜索了题解。恍然大悟,我的方法稍加修改就为正确答案了。唉,下次努力
  • 题解
  • 复杂度:O(row+col)
class Solution {
public:
    bool Find(int target, vector > array) {
        size_t row = array.size();
        if (row == 0)
            return false;
        size_t col = array[0].size();
        
        int i = 0, j = col - 1;
        while(i < row && j >= 0){
            if (array[i][j] == target)
                return true;
            else if (array[i][j] > target)
                --j;
            else
                ++i;
        }
        return false;
    }
};

小结

最近感觉自己有点迷失,现在看来还是按部就班的向前进比较靠谱,没有刷题的日子里,整个人好像都不积极了。刷题使人向上,哈哈@@

- 知识点

  • set用法
  • 二分思想变型

你可能感兴趣的:(--算法)