Leetcode(上)

news2024/10/10 0:27:27

Leetcode(上)


1.LeetCode01

两数之和

给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。

  • 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
  • 你可以按任意顺序返回答案。

(1)暴力法

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        int i, j;
        for (i = 0; i < nums.size(); ++i) {
            for (j = i + 1; j < nums.size(); ++j) {
                if (nums[i] + nums[j] == target) {
                    return {i, j};
                }
            }
        }
        return {i, j};
    }
};

(2)二分查找

思想:sort排序 + 二分查找

  1. 使用for循环遍历数组中的每一个数字

  2. 在for循环内部,使用target值减去当前遍历的数字值获取配对值ret,使用二分查找该数字ret

  3. 如果找到该数字则直接输出其下标(初始若有序的情况下)

  4. 实际是无序的!难点在于如何联系被sort打乱下标后的vec与未打乱的nums,并从其中找出目标数字的下标?

    for (int j = 0; j < n; j++) {
        if (nums[j] == vec[i] || nums[j] == ret) result.push_back(j);
        if(result.size() == 2) return result;
    }
    
//自己写二分差查找
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {		
		vector<int> vec;
        int n = nums.size();
        //1.遍历nums将数据拷贝到vec中
		for (auto &temp: nums) {
            vec.push_back(temp);
        }
        //2.对vec进行排序
		sort(vec.begin(), vec.end());
        //3.开始二分查找
		for (int i = 0; i < n; i++) {
            //(1)获取配对值
			int ret = target - vec[i];
            //(2)查找配对值ret在vec中的下标lower_bound(array.begin(),array.end(),targetNumber)
            //该方法返回一个指针,要获取下标只需将p与array.begin()做一次减法即可
			int idx = lower_bound(vec.begin(), vec.end(), ret) - vec.begin();
			//(3)在vec中找到了配对值ret对应的下标idx
            if(0 <= idx && idx < n && vec[idx] == ret) {
				vector<int> result;
                //(4)获取配对值ret在nums中的下标(解决sort顺序打乱的问题)
				for (int j = 0; j < n; j++) {
					if (nums[j] == vec[i] || nums[j] == ret) result.push_back(j);
					if(result.size() == 2) return result;
				}
			}
		}
        return {};
    }
};
//利用stl提供的lower_bound二分查找
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> vec;
        //1.遍历nums将数据拷贝到vec中
		for (auto &temp: nums) {
            vec.push_back(temp);
        }
        //2.对vec进行排序
        sort(vec.begin(), vec.end());
        //3.开始二分查找
        for (int i = 0; i < vec.size(); ++i) {
            //(1)获取配对值
            int ret = target - vec[i];
            //(2)二分查找配对值ret
            int l = i + 1;
            int r = vec.size() - 1;
            while (l <= r) {
                int mid = (l + r) / 2;
                if (ret == vec[mid]) {
                    //从有序的vec中找到对应在无序的nums中的下标
                    vector<int> result;
                    for (int j = 0; j < vec.size(); ++j) {
                        if (nums[j] == vec[i] || nums[j] == ret) result.push_back(j);
					    if(result.size() == 2) return result;
                    }
                }
                if (ret < vec[mid]) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            }
        }
        return {};
    }
};

(3)双指针

思想:sort排序 + 双指针法

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> vec;
        //1.遍历nums将数据拷贝到vec中
		for (auto &temp: nums) {
            vec.push_back(temp);
        }
        //2.对vec进行排序
        sort(vec.begin(), vec.end());
        //3.使用双指针法在有序vec容器中进行查找
        int l = 0;
        int r = vec.size() - 1;
        while (l < r) {
            int sum = vec[l] + vec[r];
            if (sum == target) {
                vector<int> result;
                for (int i = 0; i < nums.size(); i++) {
					if (nums[i] == vec[r] || nums[i] == vec[l]) result.push_back(i);
					if(result.size() == 2) return result;
				}
            }
            if (sum > target) {
                --r;
            } else {
                ++l;
            }
        }
        return {};
    }
};

(4)哈希表

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int> hashmap;
        vector<int> result(2,-1);
        for (int i = 0; i < nums.size(); i++) {
            hashmap.insert(map<int, int>::value_type(nums[i], i));
        }
        for (int i = 0; i < nums.size(); i++) {
            //判定是否找到目标元素 且目标元素不能是本身
            if(hashmap.count(target - nums[i]) > 0 && (hashmap[target - nums[i]] != i)) {
                result[0] = i;
                result[1] = hashmap[target - nums[i]];
                break;
            }
        }
        return result;
    };
};

哈希表优化(减少for循环次数):

  1. 在进行迭代将元素插入到表中的同时,就可以马上进行检查,表中是否已经存在当前元素所对应的目标元素
  2. 如果存在,那我们已经找到了对应解,并立刻将其返回
//哈希表优化
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int, int> hashmap;
        vector<int> result(2,-1);
        for(int i = 0; i < nums.size(); ++i) {
            if (hashmap.count(target - nums[i]) > 0) {
                //1.检查表中是否已经存在当前元素所对应的目标元素
                result[0] = hashmap[target - nums[i]];
                result[1] = i;
                break;
            } else {
                //2.若不存在则再将下标与data反过来放入map中,以便用来获取下标
                hashmap[nums[i]] = i;
            }
        }
        return result;
    };
};

2.LeetCode07

整数反转

给你一个 32 位的有符号整数 x ,返回其数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)(只允许使用int类型的变量)

提示:-231 <= x <= 231 - 1

input:120
output:21
input:0
output:0
class Solution {
public:
    int reverse(int x) {
        int ans = 0;
        while (x) {
            if (ans > INT_MAX / 10 || ans < INT_MIN / 10 ||
                ans == INT_MAX / 10 && x % 10 > 7 ||
                ans == INT_MIN / 10 && x % 10 < -8
            ) {
                ans = 0;
                break;
            }
            ans = ans * 10 + x % 10;
            x /= 10;
        }
        return ans;
    }
};

3.LeetCode09

回文数

给你一个整数 x ,如果 x 是一个回文整数,返回 true;否则返回 false。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

提示:-231 <= x <= 231 - 1

(1)整数反转

利用整数反转的思想,来处理回文数字问题

class Solution {
public:
    bool isPalindrome(int x) {
        if (x < 0) return false;
        long long ans = 0;
        long long raw = x;
        while (x) {
            ans = ans * 10 + x % 10;
            x /= 10;
        }
        return raw == ans;
    }
};

(2)字符串反转

class Solution {
public:
    bool isPalindrome(int x) {
        if (x < 0) return false;
        string raw = to_string(x);
        string ans = raw;
        for (int i = 0, j = raw.length() - 1; i < j; ++i, --j) {
            char c = ans[i];
            ans[i] = ans[j];
            ans[j] = c;
        }
        return raw == ans;
    }
};

4.LeetCode13

罗马数组转整数

罗马数字包含以下七种字符:I, V, X, L,C,D 和 M。

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII 而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值。同样地数字9表示为 IX。

这个特殊的规则只适用于以下六种情况:

  • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
  • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个罗马数字,将其转换成整数。

class Solution {
public:
    int romanToInt(string s) {
        int ans = 0;
        for (int i = 0; i < s.length(); ++i) {
            if (s[i] == 'I') {
                //特殊判断
                if (s[i + 1] == 'V' || s[i + 1] == 'X') {
                    ans += (s[i + 1] == 'V' ? 4 : 9);
                    i++;
                } else {
                    ans += 1;
                }
            } else if (s[i] == 'V') {
                ans += 5;
            } else if (s[i] == 'X') {
                //特殊判断
                if (s[i + 1] == 'L' || s[i + 1] == 'C') {
                    ans += (s[i + 1] == 'L' ? 40 : 90);
                    i++;
                } else {
                    ans += 10;
                }
            } else if (s[i] == 'L') {
                ans += 50;
            } else if (s[i] == 'C') {
                //特殊判断
                if (s[i + 1] == 'D' || s[i + 1] == 'M') {
                    ans += (s[i + 1] == 'D' ? 400 : 900);
                    i++;
                } else {
                    ans += 100;
                }
            } else if (s[i] == 'D') {
                ans += 500;
            } else if (s[i] == 'M') {
                ans += 1000;
            } else {
                return -1;
            }
        }
        return ans;
    }
};

5.LeetCode14

最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串。

//解法1:暴力循环 + substr字符串截取
/*runtime beats 73.15 % of cpp submissions
memory usage beats 27.86 % of cpp submissions (9 MB)
*/
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        if (strs.size() == 0) return "";
        string ans = strs[0];
        for (int i = 1; i < strs.size(); ++i) {
            int index = 0;
            for (;index < max(strs[i].length(), ans.length()) && ans[index] == strs[i][index]; ++index);
            ans = strs[i].substr(0, index);
        }
        return ans;
    }
};

//解法2:暴力循环 + 字符串的+=操作(取消了对substr的引用,性能更优!)
/*runtime beats 73.15 % of cpp submissions
memory usage beats 92.63 % of cpp submissions (8.8 MB)
*/
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        if (strs.size() == 0) return "";
        string ans = strs[0];
        string temp;
        for (int i = 1; i < strs.size(); ++i) {
            temp = ans;
            ans = "";//避开新字符串长度更小的问题
            for (int j = 0; j < strs[i].length() && j < temp.length(); ++j) {
                if (strs[i][j] == temp[j]) {
                    ans += temp[j];
                } else {
                    break;
                }
            }
        }
        return ans;
    }
};

在这里插入图片描述

6.LeetCode26

删除有序数组中的重复项

不要使用额外的空间,你必须在 原地修改输入数组 并在使用 O(1) 额外空间的条件下完成。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if (nums.size() == 0) return 0;
        int black = 0;
        for (int red = 1; red < nums.size(); ++red) {
            if (nums[red] != nums[black]) {
                black++;
                nums[black] = nums[red];
            }
        }
        return black + 1;
    }
};

7.LeetCode27

移除指定元素

(1)巧妙的移动元素

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int count = 0;
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] == val) {
                count++;
            } else {
                nums[i - count] = nums[i];
            }
        }
        return nums.size() - count;
    }
};

(2)重复项删除类似

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int black = 0;
        for (int red = 0; red < nums.size(); ++red) {
            if (nums[red] != val) {
                nums[black] = nums[red];
                black++;
            }
        }
        return black;
    }
};

8.LeetCode35

搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

(1)暴力法

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] >= target) return i;
        }
        return nums.size();
    }
};

(2)二分查找

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        if (nums[nums.size() - 1] < target) return nums.size();
        int l = 0, r = nums.size() - 1;
        while (l != r) {
            int mid = (l + r) / 2;
            if (nums[mid] >= target) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return l;
    }
};

9.LeetCode38

外观数列

给定一个正整数 n,输出外观数列的第 n 项。

外观数列是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。你可以将其视作是由递归公式定义的数字字符串序列

  • countAndSay(1) = "1"
  • countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。

前五项如下:

1.     1
2.     11
3.     21
4.     1211
5.     111221
第一项是数字 1 
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"

要描述一个数字字符串,首先要将字符串分割为最小数量的组,每个组都由连续的最多相同字符组成。

对于每个组,先描述字符的数量然后描述字符,形成一个描述组。

  • 要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。
  • 例如,数字字符串 "3322251" 的描述如下图:

在这里插入图片描述

//遍历前一个字符串 得到后一个字符串
class Solution {
public:
    void work(string &str, int cnt, char c) {
        str += (char)(cnt + '0');//数字数量
        str += c;//数字字符
    }
    void func(string &str1, string &str2) {
        int cnt = 0;
        for (int i = 0; i < str1.length(); ++i) {
            if (cnt == 0 || str1[i] == str1[i - 1]) {
                cnt++;
            } else {
                work(str2, cnt, str1[i - 1]);
                cnt = 1;
            }
        }
        work(str2, cnt, str1[str1.length() - 1]);
    }
    string countAndSay(int n) {
        string ans[35] = {"", "1"};
        for (int i = 2; i <= n; ++i) {
            func(ans[i - 1], ans[i]);
        }
        return ans[n];
    }
};
//利用斐波那契数列求解的思维 进行优化
class Solution {
public:
    void work(string &str, int cnt, char c) {
        str += (char)(cnt + '0');//数字数量
        str += c;//数字字符
    }
    void func(string &str1, string &str2) {
        int cnt = 0;
        for (int i = 0; i < str1.length(); ++i) {
            if (cnt == 0 || str1[i] == str1[i - 1]) {
                cnt++;
            } else {
                work(str2, cnt, str1[i - 1]);
                cnt = 1;
            }
        }
        work(str2, cnt, str1[str1.length() - 1]);
    }
    string countAndSay(int n) {
        string ans[2] = {"", "1"};
        int a = 0, b = 1;
        for (int i = 2; i <= n; ++i) {
            ans[a].clear();
            func(ans[b], ans[a]);
            swap(a, b);
        }
        return ans[b];
    }
};

10.LeetCode20

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。
  • 每个右括号都有一个对应的相同类型的左括号。

(1)由简到繁

可以将问题先简化为1种括号的匹配问题(判断左括号、右括号的数量是否相等),再扩展括号匹配的种类:

在这里插入图片描述

  1. +1可以等价为进入,-1可以等价为出去
  2. 一对()可以等价为一个完整的事件
  3. (())可以看做事件与事件之间的完全包含关系

1种括号的匹配问题

//写法1
bool isValid(char *s) {
    int lum = 0, rnum = 0;
    int len = strlen(s);
    for (int i = 0; i < len; ++i) {
        switch (s[i]) {
            case '(' : ++lnum; break;
            case ')' : ++rnum; break;
            default : return flase;
        }
        if (lnum >= rnum) continue;
        return false;
    }
	return lnum = rnum;
}
//写法2
bool isValid(char *s) {
    int lum = 0;
    int len = strlen(s);
    for (int i = 0; i < len; ++i) {
        switch (s[i]) {
            case '(' : ++lnum; break;
            case ')' : --rnum; break;
            default : return flase;
        }
        if (lnum >= 0) continue;
        return false;
    }
	return lnum = 0;
}

多种括号的匹配问题

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

bool judgeOne(char *s, int *i, int d) {
    bool flag = true;
    int j = d;
    while (s[*i] && flag) {
        switch (s[*i]) {
            case '(' :
                ++(*i);
                flag = judgeOne(s, i, d + 1);
                if (s[*i] == ')') {++(*i); flag &= true;}
                else if (s[*i] == ']' || s[*i] == '}' || s[*i] == '\0') flag = false;
                break;
            case '[' :
                ++(*i);
                flag = judgeOne(s, i, d + 1);
                if (s[*i] == ']') {++(*i); flag &= true;}
                else if (s[*i] == ')' || s[*i] == '}' || s[*i] == '\0') flag = false;
                break;
            case '{' :
                ++(*i);
                flag = judgeOne(s, i, d + 1);
                if (s[*i] == '}') {++(*i); flag &= true;}
                else if (s[*i] == ')' || s[*i] == ']' || s[*i] == '\0') flag = false;
                break;
            case ')' :
            case ']' :
            case '}' :
                return j = 0 ? false : true && flag;
            default :
                return false;
        }
    }
    return flag;
}

bool isValid(char * s) {
    int i = 0, len = strlen(s);
    bool flag = true;
    while (i < len && flag) {
        flag &= judgeOne(s, &i, 0);
    }
    return flag;
}

int main() {
    char s[1000];
    cin >> s;
    cout << s << " isValid : " << isValid(s) << endl;
    return 0;
}

注意:该程序虽然可以判断成功,但是执行的时间复杂度太高导致超时。

(2)利用Stack解决:

#include <iostream>
using namespace std;

typedef struct Stack {
  char *base;
  int top;
  int stackSize;
} Stack;

void InitStack(Stack &s, int n) {
  s.base = new char[100000];
  // s->base = (int *)malloc(sizeof(int) * n);
  // s->base = malloc(stackSize);
  s.stackSize = n;
  s.top = -1;
};

bool EmptyStack(Stack &s) { return s.top == -1; }

void PushStack(Stack &s, char c) {
  s.top++;
  s.base[s.top] = c;
}

void PopStack(Stack &s) { s.top--; }

char GetTop(Stack &s) { return s.base[s.top]; }

bool isValid(string s) {
  int len = s.length();
  Stack stack;
  InitStack(stack, len);
  for (int i = 0; i < len; ++i) {
    switch (s[i]) {
      case '(':
      case '[':
      case '{':
        PushStack(stack, s[i]);
        break;
      case ')':
        if (EmptyStack(stack)) return false;
        if (GetTop(stack) != '(') return false;
        PopStack(stack);
        break;
      case '}':
        if (EmptyStack(stack)) return false;
        if (GetTop(stack) != '{') return false;
        PopStack(stack);
        break;
      case ']':
        if (EmptyStack(stack)) return false;
        if (GetTop(stack) != '[') return false;
        PopStack(stack);
        break;
    }
  }
  return EmptyStack(stack);
}

int main() {
  char s[1000];
  cin >> s;
  cout << s << "isValid : " << isValid(s) << endl;
  return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/190868.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构——优先级队列和堆

目录 一、堆 1.概念 2.堆的存储方式 3.性质 4.模拟实现堆&#xff08;以小根堆为例&#xff09; &#xff08;1&#xff09;.堆的调整 &#xff08;2&#xff09;.堆的创建 &#xff08;3&#xff09;.建堆的时间复杂度 &#xff08;4&#xff09;.堆的插入和删除 5.堆…

微服务篇之Eureka注册中心

目录 1. 初识Eureka 1.1 Eureka是什么 1.2 什么是注册中心 1.3 Eureka的原理 2. Eureka的快速入门 2.1 搭建eureka的单机服务 2.2 注册服务的消费者 2.3 注册服务的提供者 3. Eureka的特性 3.1 自我保护机制 3.2 集群支持AP特性 4. Eureka的集群 4.1 不分区集群模式 4.2 分…

Go语言测试(回归测试、集成测试、单元测试简述)与项目开发的流程简述

测试项目流程1. 测试的类别2. 单元测试的规则&#xff08;函数以Test开头&#xff09;2.1 示例12.2 示例23. Mock测试&#xff08;打桩&#xff09;4. 基准测试&#xff08;类似于单元测试&#xff0c;函数以Benchmark开头&#xff09;5. 项目开发的流程项目拆解代码设计测试运…

浪涌保护器(电涌保护器)连接线规格分析方案

低压配电设计中&#xff0c;现在对于浪涌保护器(SPD)及其专用保护装置的标注和画法&#xff0c;都比较规范统一了。那有没有遇到要求标注浪涌保护器连接线规格的情况&#xff1f;或者说&#xff0c;设计师有没有责任要标注清楚各类浪涌保护器连接线规格&#xff1f;地凯科技防雷…

屈光发育档案是什么?为什么专业医生建议从3岁开始就要建立?

当孩子出现近视问题时&#xff0c;家长们都会很焦虑。其实儿童视力发育是一个循序渐进&#xff0c;逐渐成长完善的过程。我们唯一能做的就是预防&#xff0c;在未近视时提前发现近视的趋势。来源&#xff1a;卫生健康委网站这其中最为关键的是建立屈光发育档案。国家青少年近视…

视频剪辑有这6个高清视频素材库就够了

视频剪辑必备的6个网站&#xff0c;免费、可商用&#xff0c;建议收藏&#xff01; 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYxMjky 菜鸟图库网素材类型非常多&#xff0c;平面设计、UI设计、电商类、图片、视频、音频等素材站内都能找到。视频素材全部高清、无…

C++——map和set封装实现

目录 mao和set模拟实现 模拟实现 取K的仿函数 Insert 迭代器 begin和end 和-- operator[] 完整代码 set.h map.h rbtree.h mao和set模拟实现 STL map和set只是包含了几个头文件 主要在选中的这个文件里&#xff0c;打开之后我们可以看到红黑树 用红黑树…

【操作系统】第二章 进程与线程

文章目录第二章 知识体系2.1 进程与线程2.1.1 进程的概念和特征2.1.2 进程的状态与转换2.1.3 进程的组成2.1.4 进程控制2.1.5 进程通信2.1.6 进程的上下文切换2.1.7 线程和多线程模型2.2 处理机调度2.2.1 调度的概念2.2.2 调度的层次分类2.2.3 调度的实现2.2.4 典型的调度算法2…

【八大数据排序法】选择排序法的图形理解和案例实现 | C++

第十五章 选择排序法 目录 第十五章 选择排序法 ●前言 ●认识排序 ●一、选择排序法是什么&#xff1f; 1.简要介绍 2.图形理解 3.算法分析 ●二、案例实现 1.案例一 ● 总结 前言 排序算法是我们在程序设计中经常见到和使用的一种算法&#xff0c;它主要是将一堆不规则…

活体识别3:论文笔记之《FACE ANTI-SPOOFING BASED ON COLOR TEXTURE ANALYSIS》

说明 本文是我对论文《FACE ANTI-SPOOFING BASED ON COLOR TEXTURE ANALYSIS》做的一个简单笔记。 这个论文是芬兰奥卢大学(Oulu)课题组的一篇很有代表性的论文&#xff0c;写于2015年&#xff0c;使用的是“LBP特征SVM分类器”这种比较传统的方案&#xff0c;方案不复杂&…

如何使用 JuiceFS 创建 WebDAV 共享

WebDAV 是一种基于 HTTP 的文件共享协议&#xff0c;最初被设计用于多用户文档协作编辑的场景&#xff0c;也被广泛应用在基于互联网的文件存储、数据同步等网盘类应用场景。 手机端和 PC 端有大量的应用内置了对 WebDAV 的支持&#xff0c;比如知名的文献管理工具 Zotero、iP…

微信小程序 java Springboot校园租房指南房屋租赁系统

东前端&#xff1b;首页、房源信息、租房指南、我的&#xff0c;用户前端&#xff1b;首页、房源信息、租房指南、我的等主要功能模块的操作和管理。 1.出租房源信息的上传、审核、发布&#xff1b; 2.租房信息的浏览、查找、查看&#xff1b; 3.用户与出租方通信&#xff1b; …

Docker-01基本命令

1、Docker安装 系统镜像为Centos7.x yum包更新到最新 sudo yum update安装需要的软件包&#xff0c;yum-util提供yum-config-manager功能。另外两个是devicemapper驱动依赖的 sudo yum install -y yum-utils device-mapper-persistent-data lvm2设置yum源为阿里云 sudo yu…

OpenText 企业内容管理平台客户案例——印度鲁宾(Lupin)制药公司

OpenText 企业内容管理平台客户案例——印度鲁宾&#xff08;Lupin&#xff09;制药公司 公司&#xff1a;Lupin 行业&#xff1a;制药 方案&#xff1a; OpenText™ Extended ECM Platform OpenText™ AppWorks™ OpenText™ Capture 合作伙伴&#xff1a;Muraai Informat…

uniapp数据缓存与apk打包

目录 一、uniapp数据缓存Storage 1.1、存值uni.setStorageSync(KEY,DATA) 1.2、取值uni.getStorageSync(KEY) 1.3、uni.removeStorageSync(KEY) 1.4、uni.clearStorageSync() 二、配置发行H5--打包 一、uniapp数据缓存Storage 1.1、存值uni.setStorageSync(KEY,DATA) 含…

APISIX介绍和安装使用

APISIX目录什么是APISIX&#xff1f;与 Kong的比较概述安装1. 安装依赖2 安装 Apache APISIX2.1 安装脚本2.2 启动 APISIXAPISIX 控制台动态负载均衡1. 启动2个微服务命令2.验证服务是否正常3. 重要概念4.创建 APISIX Upstream&#xff08;上游&#xff0c;后端 API 服务&#…

Python(12)--元组

一、元组的基本介绍 元组&#xff08;tuple&#xff09;&#xff1a;这种数据类型结构与列表相同&#xff0c;但它与列表也有很大的差异&#xff0c;它的元素值与元素个数不可更改。 列表的定义是将元素放入[ ]中&#xff0c;元组的定义是将元素放入&#xff08;&#xff09;中…

通过堆转储快照定位JVM堆内存OOM的问题

目录获取堆转储快照JVM启动时增加参数通过jmap指令生成分析堆转储快照Eclipse Memory Analyzer简介示例获取堆转储快照 如何获取堆转储快照&#xff1f;常用的有两种方式&#xff1a; JVM启动时增加参数 出现OOM时生成堆dump&#xff1a; -XX:HeapDumpOnOutOfMemoryError指…

【2325. 解密消息】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你字符串 key 和 message &#xff0c;分别表示一个加密密钥和一段加密消息。解密 message 的步骤如下&#xff1a; 使用 key 中 26 个英文小写字母第一次出现的顺序作为替换表中的字母 顺序 。将…

【数据结构初阶】第六篇——二叉树的重要性质

树的概念及结构 树的概念 树中专有名词 树的表示 二叉树的概念及其重要性质 二叉树的概念 数据结构中的二叉树 特殊的二叉树 二叉树的性质 二叉树的存储结构 顺序结构 链式结构 树的概念及结构 树的概念 树是一种非线性的数据结构&#xff0c;它是由n(n>0)个有…