当前位置: 首页 > news >正文

【数据结构与算法】LeetCode:双指针法

文章目录

  • LeetCode:双指针法
    • 正序同向而行(快慢指针)
      • 移除元素
      • 移动零(Hot 100)
      • 删除有序数组中的重复项
      • 颜色分类(Hot 100)
      • 压缩字符串
      • 移除链表元素
      • 删除排序链表中的重复元素
      • 删除排序链表中的重复元素 II
      • 反转链表 (Hot 100)
      • 删除链表的倒数第 N 个结点 (Hot 100)
      • 链表的中间结点
      • K 个一组翻转链表 (Hot 100)
      • 排序链表 (Hot 100)
    • 倒序同向而行
      • 合并两个有序数组(Hot 100)
      • 寻找两个正序数组的中位数(Hot 100)
      • 字符串相加
      • 反转字符串中的单词
    • 相向而行
      • 有序数组的平方
      • 盛最多水的容器 (Hot100)
      • 接雨水 (Hot 100)
      • 三数之和 (Hot 100)
      • 反转字符串
    • 滑动窗口
      • 无重复字符的最长子串(Hot100)
      • 找到字符串中所有字母异位词(Hot100)
      • 最小覆盖子串(Hot100)
      • 滑动窗口最大值(Hot100)

LeetCode:双指针法

双指针法通常是指使用两个指针相向而行或同向而行来遍历对象(如数组、链表或字符串),以避免多层循环,从而降低算法的时间复杂度。

正序同向而行(快慢指针)

移除元素

移除元素

class Solution {
public:int removeElement(vector<int>& nums,  int val) {int slow = 0, fast = 0; while (fast < nums.size()) {  if (nums[fast] != val) {       // fast_i没遇到目标值nums[slow] = nums[fast];   // 保留 nums[fast]// slow和fast都前进一步slow++;    fast++; }else{                         // 遇到目标值,slow不动,fast前进一步fast++; }}return slow;    }
};

简化代码:

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

移动零(Hot 100)

移动零

class Solution {
public:void moveZeroes(vector<int>& nums) {int  slow = 0, fast = 0;while (fast < nums.size()) {if (nums[fast] != 0) { // fast 指向非零数,swap(nums[slow], nums[fast]); // 保留非零数slow++;  // slow和fast 都前进一步  }fast++; // 指向零数 slow不动,fast前进一步}}
};

删除有序数组中的重复项

删除有序数组中的重复项

class Solution {
public:int removeDuplicates(vector<int>& nums) {int fast = 1, slow = 1;while (fast <  nums.size()) {// fast 没指向重复项,slow和fast都移动if (nums[fast] != nums[fast - 1]) {nums[slow] = nums[fast]; // 保留非重复项slow++;   // slow指向未保留的元素,可能是要去除的元素}fast++;  // fast指向重复项,则不让slow移动}return slow;}
};

颜色分类(Hot 100)

颜色分类

class Solution {
public:void sortColors(vector<int>& nums) {int slow = 0, fast = 0;// 把0往前移while(fast < nums.size()) {if (nums[fast] == 0) {swap(nums[fast], nums[slow]);++slow;}++fast;}fast = slow;// 把1往前移while(fast < nums.size()) {if (nums[fast] == 1) {swap(nums[fast], nums[slow]);++slow;}++fast;}}
};

压缩字符串

压缩字符串

class Solution {
public:int compress(vector<char>& chars) {int slow = 0;int fast = 0;while(fast < chars.size()){char cur = chars[fast];int count = 0;         // 重复数量while(fast < chars.size() && chars[fast] == cur){fast++;count++;}chars[slow++] = cur;   // 记录当前字符if(count > 1){         // 记录当前字符重复数量for(char c: to_string(count)) chars[slow++] = c;}}return slow;}   
};

移除链表元素

移除链表元素

class Solution {
public:ListNode* removeElements(ListNode* head, int val) {ListNode* dummy_head = new ListNode(0, head);ListNode* cur = dummy_head;// 双指针:cur和 cur.nextwhile(cur->next != nullptr){if(cur->next->val != val){cur = cur->next;}else{cur->next = cur->next->next;}}return dummy_head->next;}
};

删除排序链表中的重复元素

删除排序链表中的重复元素

class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {if (head == nullptr) return head;// 第一个节点肯定不是重复元素ListNode* cur = head;// 双指针:cur和 cur.nextwhile(cur->next != nullptr){if(cur->next->val != cur->val){cur = cur->next;}else{cur->next = cur->next->next;}}return head;}
};

删除排序链表中的重复元素 II

删除排序链表中的重复元素 II

class Solution {
public:ListNode* deleteDuplicates(ListNode* head) {ListNode* hair = new ListNode(0,head);ListNode* cur = hair;while(cur->next && cur->next->next){if(cur->next->next->val == cur->next->val) // 数值val存在重复{int val = cur->next->val;   // 记录数值// 去掉cur->next之后所有值为val的节点while(cur->next && cur->next->val == val){ cur->next = cur->next->next;}}else{cur = cur->next;}   }return hair->next;}
};

反转链表 (Hot 100)

反转链表

class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode* prev = nullptr;ListNode* cur = head;while(cur){ListNode* temp = cur->next;cur->next = prev;prev = cur;cur =temp;}return prev;}
};

删除链表的倒数第 N 个结点 (Hot 100)

删除链表的倒数第 N 个结点

class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode* dummy = new ListNode(0, head);// 相邻节点fast slowListNode* fast = head;ListNode* slow = dummy;// 使得slow和fast之间的节点数为nfor (int i = 0; i < n; ++i) fast = fast->next;  // 同时移动slow和fast,直到fast为nullptrwhile (fast) {fast = fast->next;slow = slow->next;}// 删除倒数第n个节点slow->next = slow->next->next;return dummy->next;}
};

链表的中间结点

链表的中间结点

class Solution {
public:ListNode* middleNode(ListNode* head) {ListNode* slow = head;ListNode* fast = head;while (fast != nullptr && fast->next != nullptr) {// fast 速度是slow的两倍,fast达到尾部时,slow到达中间slow = slow->next;fast = fast->next->next;}return slow;}
};

K 个一组翻转链表 (Hot 100)

K 个一组翻转链表


class Solution {
private:void reverseGroup(ListNode*& head, ListNode*& tail,int k){ListNode* pre = nullptr;ListNode* cur = head;for(int i = 0 ; i< k; i++){ListNode* temp = cur->next;cur->next = pre;pre = cur;cur = temp;}}public:ListNode* reverseKGroup(ListNode* head, int k) {ListNode* dummy = new ListNode(0,head);ListNode* tail = dummy;while(head){ListNode* pre = tail; for(int i = 0 ;i < k; i++){tail = tail->next;// 如果节点总数不是 k 的整数倍,那么最后剩余的节点保持原有顺序。if(!tail) return dummy->next;}ListNode* temp = tail->next;reverseGroup(head, tail, k);swap(head, tail);  // 子链表头变成尾,尾变成头// 把子链表重新接回原链表pre->next = head;tail->next = temp;head = temp;}return dummy->next;}
};

排序链表 (Hot 100)

排序链表

class Solution {
public:ListNode* sortList(ListNode* head) {if (head == nullptr)  return head;return sort(head, nullptr);}// 归并排序ListNode* sort(ListNode* head, ListNode* tail) {// 如果链表只有一个节点,将其与后续节点断开并返回该节点if (head->next == tail) {head->next = nullptr;return head;}ListNode* slow = head, *fast = head;while (fast != tail && fast->next != tail) {slow = slow->next;fast = fast->next->next;}ListNode* mid = slow;return merge(sort(head, mid), sort(mid, tail));}// 升序合并ListNode* merge(ListNode* head1, ListNode* head2) {ListNode* dummyHead = new ListNode(0);ListNode* temp = dummyHead, *temp1 = head1, *temp2 = head2;while (temp1 != nullptr && temp2 != nullptr) {if (temp1->val <= temp2->val) {temp->next = temp1;temp1 = temp1->next;} else {temp->next = temp2;temp2 = temp2->next;}temp = temp->next;}if (temp1 != nullptr)  temp->next = temp1;     else if (temp2 != nullptr) temp->next = temp2;return dummyHead->next;}
};

倒序同向而行

合并两个有序数组(Hot 100)

合并两个有序数组

class Solution {
public:void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {int i = nums1.size() - 1;m--;n--;while(n >= 0){if(m >= 0 && nums1[m] > nums2[n]) nums1[i--] = nums1[m--];else nums1[i--] = nums2[n--]; }}
};

寻找两个正序数组的中位数(Hot 100)

寻找两个正序数组的中位数

class Solution {
public:double findMedianSortedArrays(std::vector<int>& nums1, std::vector<int>& nums2) {  std::vector<int> merged;  int i = 0, j = 0;  int m = nums1.size(), n = nums2.size();  // 合并两个数组  while (i < m && j < n) {  if (nums1[i] < nums2[j]) {  merged.push_back(nums1[i++]);  } else {  merged.push_back(nums2[j++]);  }  }  // 添加剩余的元素  while (i < m) merged.push_back(nums1[i++]); while (j < n)  merged.push_back(nums2[j++]);  int totalSize = merged.size();  if (totalSize % 2 == 1) {  // 奇数个元素,中位数是中间的那个  return merged[totalSize / 2];  } else {  // 偶数个元素,中位数是中间两个数的平均值  return (merged[totalSize / 2 - 1] + merged[totalSize / 2]) / 2.0;  }  }  
};

字符串相加

字符串相加

class Solution {
public:string addStrings(string num1, string num2) {int i = num1.size() - 1;int j = num2.size() - 1;int add = 0;string result = "";while(i >= 0 || j >= 0 || add > 0){int x = i >= 0 ? num1[i] - '0' : 0;int y = j >= 0 ? num2[j] - '0' : 0;int val = x + y + add;result.push_back('0' + val % 10);add = val / 10;i --; j--;}reverse(result.begin(), result.end());return result;}
};

反转字符串中的单词

反转字符串中的单词

// https://leetcode.cn/problems/reverse-words-in-a-string/solutions/2361551/151-fan-zhuan-zi-fu-chuan-zhong-de-dan-c-yb1r/class Solution {
public:std::string reverseWords(std::string s) {std::vector<std::string> wordsVector; // 存储分割后的单词的向量int i, j;i = s.size() - 1; // i 从字符串末尾开始向前扫描j = i; // j 用于标记单词的尾字符索引while (i >= 0) {// 跳过单词间的空格while (i >= 0 && s[i] == ' ')  i--;j = i; // 更新单词的尾字符索引while (i >= 0 && s[i] != ' ') i--; // 找到单词前的空格// 将找到的单词添加到向量中(注意要避免将空格作为单词存储)if (i != j)  wordsVector.push_back(s.substr(i + 1, (j - i)));}std::string result;// 将向量中的单词连接成一个字符串for (int n = 0; n < wordsVector.size(); ++n) {result += wordsVector[n];if (n != wordsVector.size() - 1) result += ' '; // 添加单词间的空格}return result;}
};

相向而行

有序数组的平方

有序数组的平方

class Solution {
public:vector<int> sortedSquares(vector<int>& nums) {vector<int> result(nums.size());int l = 0;int r = nums.size() - 1;int pos = nums.size() - 1;// 非递减数组平方后,数值由两侧向中间递减while(l <= r){// 左侧的值比右侧的值高if(nums[l] * nums[l] > nums[r] * nums[r]){result[pos] = nums[l] * nums[l];l++; }else{ // 右侧的值比左侧的值高result[pos] = nums[r] * nums[r];r--;}pos--;}return result;}
};

盛最多水的容器 (Hot100)

盛最多水的容器

class Solution {
public:int maxArea(vector<int>& height) {int l = 0;int r = height.size() - 1;int result = 0;while(l < r){int capacity = min(height[l],height[r])*(r -l);result = max(result, capacity);// 宽度缩小,尝试增大最小高度if(height[l] <= height[r]) l++;  else r--;}return result;}
};

接雨水 (Hot 100)

接雨水

class Solution {
public:int trap(vector<int>& height) {int l = 0;int r = height.size() - 1;int ans = 0;int left_max = INT_MIN;int right_max = INT_MIN;while(l < r){left_max = max(left_max, height[l]);right_max = max(right_max, height[r]);if(height[l] < height[r] ){   // 满足: height[l] < height[r] 且 height[l] <= left_maxans += left_max - height[l];l++;}else{ans += right_max - height[r];r--;}}return ans;}
};

三数之和 (Hot 100)

三数之和

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {  vector<vector<int>> result;  // 对数组进行排序,从左到右递增sort(nums.begin(), nums.end()); for (int i = 0; i < nums.size(); i++) {  // 跳过第一个数的重复元素以避免重复的三元组  // 保证i在相同值的最左,这样left才可以取相同值if (i > 0 && nums[i] == nums[i - 1]) continue;  // a≤b≤c,保证了只有 (a,b,c)这个顺序会被枚举到int left = i + 1; int right = nums.size() - 1;  while (left < right) {  int sum = nums[i] + nums[left] + nums[right];  if (sum < 0) left++;       // 如果和小于0,右移左指针,尝试增大值 else if (sum > 0) right--; // 如果和大于0,左移右指针,尝试较小值else {   //  跳过第二个数的重复元素, 保证left为最右while (left < right && nums[left] == nums[left + 1]) left++;  //  跳过第三个数的重复元素, 保证left为最左while (left < right && nums[right] == nums[right - 1]) right--;  // 找到了一个和为0的组合  result.push_back({nums[i], nums[left], nums[right]}); // 继续寻找下一个组合left++;  right--;  }             }  }  return result;  } 
};

反转字符串

反转字符串

class Solution {
public:void reverseString(vector<char>& s) {int n = s.size();int left = 0, right = n - 1;while (left < right) {swap(s[left++], s[right--]);}}
};

滑动窗口

滑动窗口通过双指针实现,一个指针(右指针)用于扩展窗口,另一个指针(左指针)收缩窗口。与普通的双指针不同的是,滑动窗口法的计算过程一般涉及双指针之间的值,而不仅仅是两个指针指向的值。

无重复字符的最长子串(Hot100)

无重复字符的最长子串

class Solution {
public:int lengthOfLongestSubstring(string s) {if (s.size() == 0)  return 0;unordered_set<char> char_set; // 窗口内的字符int ans = 0;int left = 0;for (int right = 0; right < s.size(); right++) {while (char_set.count(s[right]) != 0)  { // 重复了char_set.erase(s[left]);left++;   // left指向s[right]最后一次出现的地方的下一个位置}ans = max(ans, right - left + 1);char_set.insert(s[right]);}return ans;}
};

找到字符串中所有字母异位词(Hot100)

找到字符串中所有字母异位词

class Solution {
public:vector<int> findAnagrams(string s, string p) {int s_len = s.size(), p_len = p.size();if (s_len < p_len) return vector<int>();vector<int> ans;// 存放字符串中字母(a-z)出现的词频vector<int> s_count(26);vector<int> p_count(26);// 当滑动窗口的首位在s[0]处时(相当于放置滑动窗口进入数组)for (int i = 0; i < p_len; ++i) {++s_count[s[i] - 'a'];  //记录s中前p_len个字母的词频++p_count[p[i] - 'a'];  //记录要寻找的字符串中每个字母的词频(只用进行一次来确定)}// 判断放置处是否有异位词if (s_count == p_count) ans.push_back(0);//开始让窗口向右进行滑动,遍历起始索引for (int i = 1; i <= s_len - p_len; ++i) { // 向右移动滑块:相当于去掉左边第一个字符,在右边加入一个字母--s_count[s[i - 1] - 'a'];            // 左边去掉的字母的词频减1++s_count[s[i + p_len - 1] - 'a'];    // 右边加入的字母的词频加1if (s_count == p_count) {      // 判断滑动后处,是否有异位词ans.push_back(i);}}return ans;}
};

最小覆盖子串(Hot100)

最小覆盖子串

class Solution {
public:// 检查当前窗口是否覆盖目标字符串bool check(unordered_map<char, int>& map_t,unordered_map<char, int>& map_s) {for (const auto& p : map_t) {if (map_s[p.first] < p.second)return false;}return true;}string minWindow(string s, string t) {// 最小覆盖子串的起始位置和长度int ans_left = -1, ans_len = INT_MAX;// map_t:记录目标字符串t中每个字符及其出现次数,// map_s:记录记录s在当前窗口内每个字符的出现次数unordered_map<char, int> map_t, map_s;// 初始化ori:记录目标字符串t每个字符及其出现次数for (const auto& c : t)++map_t[c];// 窗口左右指针int left = 0, right = 0;// 向右扩大窗口直到右指针达到s末尾while (right < int(s.size())) {// 将字符s[right]加入到map_s中if (map_t.find(s[right]) != map_t.end())++map_s[s[right]];// 当前窗口包含了目标字符串t中的所有字符时while (check(map_t, map_s) && left <= right) {if (right - left + 1 <ans_len) { // 更新最小覆盖子串的起始位置和长度ans_len = right - left + 1;ans_left = left;}// 将左指针指向的字符从cnt中移除if (map_t.find(s[left]) != map_t.end())--map_s[s[left]];// 移动左指针,缩小窗口++left;}++right; //  向右扩大窗口}// 如果ans_left仍为-1,说明s中不存在包含t的子串,返回空字符串// 否则,返回从ans_left开始,长度为len的子串return ans_left == -1 ? string() : s.substr(ans_left, ans_len);}
};

滑动窗口最大值(Hot100)

滑动窗口最大值

class Solution {
public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {if(nums.size() == 0 || k == 0) return {};deque<int> deque;  vector<int> result(nums.size() - k + 1);int  left = 1 - k,right = 0;while(right < nums.size()) {// 队列最前元素为nums[left-1],则删除if(left > 0 && deque.front() == nums[left - 1]) deque.pop_front();// 单调队列  删除小于nums[right]的数,保持 deque 递减while(!deque.empty() && deque.back() < nums[right]) deque.pop_back(); // 添加nums[right]deque.push_back(nums[right]);// 记录窗口最大值if(left >= 0) result[left] = deque.front();left++, right++;}return result;}
};

相关文章:

【数据结构与算法】LeetCode:双指针法

文章目录 LeetCode&#xff1a;双指针法正序同向而行&#xff08;快慢指针&#xff09;移除元素移动零&#xff08;Hot 100&#xff09;删除有序数组中的重复项颜色分类&#xff08;Hot 100&#xff09;压缩字符串移除链表元素删除排序链表中的重复元素删除排序链表中的重复元素…...

Istio下载及安装

Istio 是一个开源的服务网格&#xff0c;用于连接、管理和保护微服务。以下是下载并安装 Istio 的步骤。 官网文档&#xff1a;https://istio.io/latest/zh/docs/setup/getting-started/ 下载 Istio 前往Istio 发布页面下载适用于您的操作系统的安装文件&#xff0c;或者自动…...

Redis基础数据结构之 Sorted Set 有序集合 源码解读

目录标题 Sorted Set 是什么?Sorted Set 数据结构跳表&#xff08;skiplist&#xff09;跳表节点的结构定义跳表的定义跳表节点查询层数设置 Sorted Set 基本操作 Sorted Set 是什么? 有序集合&#xff08;Sorted Set&#xff09;是 Redis 中一种重要的数据类型&#xff0c;…...

蓝队技能-应急响应篇Web内存马查杀JVM分析Class提取诊断反编译日志定性

知识点&#xff1a; 1、应急响应-Web内存马-定性&排查 2、应急响应-Web内存马-分析&日志 注&#xff1a;传统WEB类型的内存马只要网站重启后就清除了。 演示案例-蓝队技能-JAVA Web内存马-JVM分析&日志URL&内存查杀 0、环境搭建 参考地址&#xff1a;http…...

递归快速获取机构树型图

一般组织架构都会有层级关系&#xff0c;根部门的parentId一般设置为null或者0等特殊字符&#xff0c;而次级部门及以下的parentId则指向他们父节点的id。 以此为基础&#xff0c;业务上经常会有查询整个组织架构层级关系的需求&#xff0c;返回对象中的children属性用来存储子…...

[Web安全 网络安全]-XSS跨站脚本攻击

文章目录&#xff1a; 一&#xff1a;前言 1.定义 2.漏洞出现的原因 3.鉴别可能存在XSS漏洞的地方 4.攻击原理 5.危害 6.防御 7.环境 7.1 靶场 7.2 自动扫描工具 7.3 手工测试工具 8.payload是什么 二&#xff1a;常用的标签语法 三&#xff1a;XSS的分类 反射…...

数据库数据恢复—SQL Server附加数据库出现“错误823”怎么恢复数据?

SQL Server数据库故障&#xff1a; SQL Server附加数据库出现错误823&#xff0c;附加数据库失败。数据库没有备份&#xff0c;无法通过备份恢复数据库。 SQL Server数据库出现823错误的可能原因有&#xff1a;数据库物理页面损坏、数据库物理页面校验值损坏导致无法识别该页面…...

Vscode 中新手小白使用 Open With Live Server 的坑

背景 最近在家学习尝试前端项目打包的一些事项&#xff0c;既然是打包&#xff0c;那么肯定就会涉及到对打包后文件的访问&#xff0c;以直观的查看打包后的效果 那么肯定就会使用到 Vscode 中 Open With LIve Server 这个功能了&#xff0c;首先这个是一个叫 Live Server 的…...

【深度学习 transformer】Transformer与ResNet50在自定义数据集图像分类中的效果比较

在深度学习领域&#xff0c;图像分类是一个经典且重要的任务。近年来&#xff0c;Transformer架构在自然语言处理领域取得了显著成功&#xff0c;逐渐被引入计算机视觉任务。与此同时&#xff0c;ResNet50作为一种经典的卷积神经网络&#xff08;CNN&#xff09;&#xff0c;在…...

【系统架构设计师】专业英语90题(附答案详解)

更多内容请见: 备考系统架构设计师-核心总结索引 文章目录 【第1~5题】【第6~10题】【第11~15题】【第16~20题】【第21~25题】【第26~30题】【第31~35题】【第36~40题】【第41~45题】【第46~50题】【第51~55题】【第56~60题】【第61~65题】【第66~70题】【第71~75题】【第76~8…...

ItemXItemEffect | ItemEffect

目录 ItemXItemEffect ItemEffectID ItemID ItemEffect ID TriggerType Charges CoolDownMSec SpellID SpellCategoryID CategoryCoolDownMSec ItemXItemEffect.db2 ItemEffectID 物品效果编号&#xff0c;取值链接 ItemEffect.db2 ItemID 物品 ID ItemEffect.d…...

web 动画库

web动画库 动画领域有一个比较知名的CSS库&#xff1a;Animate.css&#xff0c;它提供了60多种动画&#xff0c;满足一般网页的需求&#xff0c;比如淡入淡出、闪现等等一系列日常动画&#xff0c;不过虽然它能满足日常需求&#xff0c;但是一些复杂的场景就需要靠JS手动去操作…...

我的AI工具箱Tauri版-MicrosoftTTS文本转语音

本教程基于自研的AI工具箱Tauri版进行MicrosoftTTS文本转语音服务。 MicrosoftTTS文本转语音服务 是自研的AI工具箱Tauri版中的一款功能模块&#xff0c;专为实现高效的文本转语音操作而设计。通过集成微软TTS服务&#xff0c;用户可以将大量文本自动转换为自然流畅的语音文件…...

【Webpack--013】SourceMap源码映射设置

&#x1f913;&#x1f60d;Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-前端领域博主 &#x1f431;‍&#x1f409;若此文你认为写的不错&#xff0c;不要吝啬你的赞扬&#xff0c;求收藏&#xff0c;求评论&#xff0c;求一个大大的赞&#xff01;&#x1f44d;* &#x…...

创新驱动,技术引领:2025年广州见证汽车电子技术新高度

汽车行业的创新浪潮正汹涌澎湃&#xff0c;一场引领未来出行的科技盛宴即将拉开帷幕&#xff01; AUTO TECH 2025 第十二届广州国际汽车电子技术展览会将于 2025 年 11 月 20日至 22 日在广州保利世贸博览馆&#xff08;PWTC Expo&#xff09;隆重举行。 作为亚洲地区领先的汽…...

Spring Boot框架在心理教育辅导系统中的应用案例

目 录 摘 要 I ABSTRACT II 1绪 论 1 1.1研究背景 1 1.2设计原则 1 1.3论文的组织结构 2 2 相关技术简介 3 2.1Java技术 3 2.2B/S结构 3 2.3MYSQL数据库 4 2.4Springboot框架 4 3 系统分析 6 3.1可行性分析 6 3.1.1技术可行性 6 3.1.2操作可行性 6 3.1.3经济可行性 6 3.1.4法律…...

Shiro-550—漏洞分析(CVE-2016-4437)

文章目录 漏洞原理源码分析加密过程解密过程 漏洞复现 漏洞原理 Shiro-550(CVE-2016-4437)反序列化漏洞 在调试cookie加密过程的时候发现开发者将AES用来加密的密钥硬编码了&#xff0c;并且所以导致我们拿到密钥后可以精心构造恶意payload替换cookie&#xff0c;然后让后台最…...

【例题】lanqiao4425 咖啡馆订单系统

样例输入 3 2 2 1 3 1 2样例输出 3 2样例说明 输入的数组为&#xff1a;【3&#xff0c;1&#xff0c;2】 增量序列为&#xff1a;【2&#xff0c;1】 当增量 h2&#xff1a;对于每一个索引 i&#xff0c;我们会将数组元素 arr[i] 与 arr[i−h] 进行比较&#xff0c;并进行可…...

从小白到大神:C语言预处理与编译环境的完美指南(下)

从小白到大神&#xff1a;C语言预处理与编译环境的完美指南&#xff08;上&#xff09;-CSDN博客 &#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;上篇链接在这~~&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x1f446;&#x…...

3657A/B/AM/BM矢量网络分析仪

苏州新利通 3657A/B/AM/BM 矢量网络分析仪 3657系列矢量网络分析仪适用于无线通信、有线电视、教育及汽车电子等领域&#xff0c;可用于对滤波器、放大器、天线、电缆、有线电视分接头等射频元件的性能测量。该产品采用Windows操作系统&#xff1b;具有误差校准功能、时域功能…...

卸载完mathtype后,删除word加载项中的mathtype

请参考博客“卸载完mathtype后&#xff0c;word加载项中还是有mathtype的解决方法_怎么删除word加载项里的mathtype-CSDN博客”以及 “安装卸载MathType经验解决MathType DLL找不到的问题——超实用_mathtype dll cannot-CSDN博客” 如果在删除.dotm文件时&#xff0c;删不掉…...

vue 实现tab菜单切换

1、目标&#xff1a; 实现切换tab菜单&#xff0c;激活状态&#xff0c;按钮高亮&#xff0c;显示对应的菜单内容 2、实现 <template><div class"tan_menu"><ul class"container"><liclass"item"v-for"item in tab…...

大数据Flink(一百二十):Flink SQL自定义函数(UDF)

文章目录 Flink SQL自定义函数&#xff08;UDF&#xff09; 一、概述 二、​​​​​​​自定义标量函数&#xff08;UDSF&#xff09; 三、​​​​​​​​​​​​​​自定义聚合函数(UDAF) 四、 ​​​​​​​​​​​​​​自定义表值函数(UDTF) Flink SQL自定义函数…...

【图像检索】基于灰度共生矩的纹理图像检索,matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于灰度共生矩的纹理图像检索&#xff0c;用matlab实现。 一、案例背景和算法介绍 …...

【操作系统】02.深入理解操作系统

一、操作系统的定位 任何计算机系统都包含一个基本的程序集合&#xff0c;称为操作系统(OS)。笼统的理解&#xff0c;操作系统包括操作系统内核和其他程序。 由上述的宏观图其实我们就知道&#xff1a;操作系统是一款进行软硬件资源管理的软件。 二、设计操作系统的目的 操…...

【Python】探索 Errbot:多功能聊天机器人框架

不是旅行治愈了你&#xff0c;是你在路上放过了自己。 在当今的数字化时代&#xff0c;聊天机器人已成为企业与客户互动、提升工作效率和增加乐趣的重要工具。Errbot是一个高度可扩展的聊天机器人框架&#xff0c;它允许开发者使用Python轻松创建和定制机器人。本文将介绍Errb…...

Linux 调试器 GDB 使用指南

在Linux环境下开发和调试程序时&#xff0c;GNU调试器&#xff08;GDB&#xff09;是一个强大的工具。它支持多种编程语言&#xff08;如C、C、Fortran等&#xff09;&#xff0c;并且可以帮助开发人员检测、排除和修复程序中的错误。GDB能够让你在程序运行时暂停&#xff0c;查…...

MiniCPM3-4B | 笔记本电脑运行端侧大模型OpenBMB/MiniCPM3-4B-GPTQ-Int4量化版 | PyCharm环境

MiniCPM3-4B&#xff0c;轻松在笔记本电脑上运行大模型&#xff1f; 背景一、选择模型二、模型下载三、模型运行四、总结 背景 2024年9月5日&#xff0c;面壁智能发布了MiniCPM3-4B&#xff0c;面壁的测试结果声称MiniCPM3-4B表现超越 Phi-3.5-mini-instruct 和 GPT-3.5-Turbo-…...

【chromedriver编译-绕过selenium机器人检测】

有小伙伴说使用selenium没能绕过机器人检测&#xff0c;盘他。 selenium机器人检测有2种&#xff0c;一是cdp检测&#xff0c;二是webdriver特征检测。cdp检测前面的博客已写过&#xff0c;这里就提下webdriver特征检测。一、selenium简介 Selenium 是一个强大的工具&#xff…...

【JavaEE精炼宝库】HTTP | HTTPS 协议详解

文章目录 一、HTTP 简介二、HTTP 协议格式&#xff1a;2.1 抓包工具的使用&#xff1a;2.2 HTTP 请求报文格式&#xff1a;2.3 HTTP 响应报文格式&#xff1a;2.4 HTTP 协议格式总结&#xff1a; 三、HTTP 请求详解&#xff1a;3.1 刨析 URL&#xff1a;3.2 方法(method)&#…...