1.笔试题思路

1. 合并两个有序数组到其中一个数组中

  将一个数据插入另外一个数据尾部,然后排序 sort(a.begin(), a.end())。

  双指针法把两个数组中的数据存入一个临时数组中,然后将临时数组中的值赋值给指定数组。

2. 寻找链表中间节点

  快慢指针都指向head节点,慢指针前进一个,快指针前进两个。

3. 有序链表或数组转换为平衡二叉树,也就是中序遍历数组回复为平衡二叉树

  寻找中间节点,然后采用递归回复平衡二叉树,创建中间节点的二叉节点,然后该节点的左孩子指向nums(low,mid-1),右孩子指向nums(mid+1,high)。

4. 判断两个string 是否是同构的

  两个字符对应位置的字符出现的位置相同

      s.find(s[i]) != t.find(t[i]),find返回下标。

5. 比较两个string类型的版本号大小

根据 . 分隔符来计算每一段的大小,然后比较大小,然后循环进行下一位的比较。

6.二分法求中间mid值

int mid = left + (right - left) / 2; // 防止计算时溢出
int mid = (right + left) / 2; // 如果right + left值超过intmax会出现错

7. 两数相乘可能大于intmax

强制类型转换为long : long res = (long)mid*mid;

8.二分法在判断大小后:

left = mid +1;

right = mid-1;

否则可能出出现恒left<right。

9. 数组在求二分法时:为防止左边界越界。

int left = 0;
int right = nums.size(); //有边界为数组长度,方便在数组是偶数个数时的取值。
int mid = 0;
while(left <= right && left < nums.size())
 
10. 矩阵初始化一个m*n大小的矩阵,二维数组使用一定要先初始化
vector<vector<int>>v(m, vector<int>(n));
 
11. 大顶堆 小顶堆
//升序队列 小顶堆 
priority_queue <int,vector<int>,greater<int> > q;
//降序队列 大顶堆 默认大顶堆 priority_queue <int,vector<int>,less<int> >q;
常用的函数:push pop top empty
priority_queue<pair<int, int> > a; // pari型的数据,先比较第一个元素,第一个相等再比较第二个元素。第二个元素时q.top().second; 不是second();
 

17.  queue<int> q

push(elem);		//从队尾入对
pop();			//弹出队头元素
back();			//返回最后一个元素
front();		//返回队头元素
 
12. vector赋值给vector
  A.assign(B.begin(),B.end());

13.  求矩阵对角线是否相同:

matrix[i][j] == matrix[i-1][j-1]

 14.归并排序排序链表

    ListNode* sortList(ListNode* head) {
        if (head == nullptr || head->next == nullptr) return head;

        ListNode* head1 = head;
        ListNode* head2 = split(head); //寻找链表中间节点

        head1 = sortList(head1);      
        head2 = sortList(head2);

        return merge(head1, head2);    //合并两个有序链表
    }

 15. 整形转string

 string str = str + to_string(left->val);

16.树递归时将需要“累积”的变量通过传引用的方式依次往下传递即可。

比如寻找所有路径,就将path 作为一个变量再递归中调用,将结束的path再放到一个全局变量中,同一个变量再不同的路径下会有不同的值。

17. 树的先序访问:

迭代法:根左右,因为要先访问左节点,考虑栈先进后出,需要先把右节点放进栈中。

对于多叉树的访问:

    void preorder(Node* root, vector<int> &res){
        if(!root) return ;
        res.push_back(root->val); //根
        for(int i =0;i<root->children.size();i++){ //访问孩子,从左到右
            preorder(root->children[i], res);
        }
    }

18.判断一个树是否是另外一个棵树的子树,没有很好的办法,只能对主树挨个节点与子树对比。

19. 遍历元素vector和string元素 :

    string mostCommonWord(string paragraph, vector<string>& banned) {
        unordered_set<string> b;
        for (string bb : banned)
        {
            b.insert(bb);
        }
}
//unordered_set赋值操作: unordered_set<char> s(str.begin(),str.end());
string str = "hello";
string cur;
for(char c:str){
cur+=tolower(c);  //转为小写
}

 

 20.信号量的使用:

class Foo {
protected:
    sem_t one,two;
public:
    Foo(){
        sem_init(&one,0,0);
        sem_init(&two,0,0);
    }
    void first(function<void()> printFirst) {
        printFirst();
        sem_post(&one);
    }
    void second(function<void()> printSecond) {
        sem_wait(&one);
        printSecond();
        sem_post(&two);
    }
    void third(function<void()> printThird) {
        sem_wait(&two);
        printThird();
    }
}

 21. mutex互斥锁的使用:

交替打印,两个对象可以各自加锁,然后解对方的锁。

class FooBar {
private:
    int n;
    mutex mtx1,mtx2;
public:
    FooBar(int n) {
        this->n = n;
        mtx2.lock();
    }
    void foo(function<void()> printFoo) {
        for (int i = 0; i < n; i++) {
            mtx1.lock();
            printFoo();
            mtx2.unlock();
        }
    }
    void bar(function<void()> printBar) {
        for (int i = 0; i < n; i++) {
            mtx2.lock();
            printBar();
            mtx1.unlock();
        }
    }
};

 22. count统计string字符串中字符的数量:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s= "abcdefgaabbccd";
    int num =count(s.begin(),s.end(),'a'); //把a改为空格,可以统计字符串中单词的个数
    cout<<num<<endl;
}

 23.  vector<int> vec(10);

这是vector初始化,内部每个元素都是0,进行赋值时使用vec[0] = 1; vec[1]=2 进行赋值,如果再直接使用push_back()方式直接往里赛数据,那会出现0000000012的样子。

也就是初始化后只能使用下标进行赋值。直接vector<int> vec;方式初始化,可以不指定下标赋值,内部元素都是空。

24.  max_element min_element求最大值最小值:

 int val= *max_element(vec.begin(), vec.end());

25. unordered_set赋值操作:

unordered_set<char> s(str.begin(), str.end());

 

std::unordered_set<string> words {"one", "two", "three", "four"};

 

26. sort(vec.begin(), vec.end()) 是从小到大排序的。

27. 坐标两点的距离:切比雪夫距离:简而言之就是左边两点的距离(垂直水平和对角都算距离1),就是两点形成的矩形的最长边。

对于平面上的两个点 x = (x0, y0) 和 y = (x1, y1),设它们横坐标距离之差为 dx = |x0 - x0|,纵坐标距离之差为 dy = |y0 - y1|,对于以下三种情况,我们可以分别计算出从 x 移动到 y 的最少次数:
    dx < dy:沿对角线移动 dx 次,再竖直移动 dy - dx 次,总计 dx + (dy - dx) = dy 次;
    dx == dy:沿对角线移动 dx 次;
    dx > dy:沿对角线移动 dy 次,再水平移动 dx - dy 次,总计 dy + (dx - dy) = dx 次。
可以发现,对于任意一种情况,从 x 移动到 y 的最少次数为 dx 和 dy 中的较大值 max(dx, dy),这也被称作 x 和 y 之间的 切比雪夫距离。
由于题目要求,需要按照数组中出现的顺序来访问这些点。因此我们遍历整个数组,对于数组中的相邻两个点,计算出它们的切比雪夫距离,所有的距离之和即为答案。

 28. 有返回值的递归

class Solution {
    Set<Integer> set = new HashSet<>();
    public int numColor(TreeNode root) {
        if(root == null) return 0;
        set.add(root.val);
        numColor(root.left);
        numColor(root.right);
return set.size(); //只有最外层返回,其他递归调用的返回值没有使用到。 } }

30. string 操作:char *strstr (const char *s1, const char *s2); //在s1中寻找s2,并返回指针

31. 罗马数字转整数,字符排序决定了是累加还是累减。

32. 字符串反转

string s[]="123456"; reverse(s.begin(),s.end());

33.根据数字二进制下 1 的数目排序

 自定义cmp类型:

class Solution {
public:
    int get(int x){
        int res = 0;
        while (x) {
            res += (x % 2);
            x /= 2;
        }
        return res;
    }
    vector<int> sortByBits(vector<int>& arr) {
        vector<int> bit(10001, 0);
        for (auto x: arr) {
            bit[x] = get(x);
        }
        sort(arr.begin(), arr.end(), [&](int x, int y){
            if (bit[x] < bit[y]) {
                return true;
            }
            if (bit[x] > bit[y]) {
                return false;
            }
            return x < y;
        });
        return arr;
    }
};

 34.

 

 

posted @ 2022-01-09 21:58  dsfsadfdgd  阅读(28)  评论(0编辑  收藏  举报