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

算法打卡第一天

1.两数之和

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

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> tatal;for(int i = 0; i < nums.size() - 1; i++)//遍历数组{for(int j = i + 1; j < nums.size() ; j++)//从第二个开始防止重和{if(target == nums[i] + nums[j])//target 等于那个数{tatal.push_back(i);tatal.push_back(j);}}}std::cout  << "[";for(int i = 0 ; i <tatal.size(); i++){std::cout <<  tatal[i] << "," << std::endl;}std::cout  << "]";return tatal;}};

2.两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

img

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

提示:

  • 每个链表中的节点数在范围 [1, 100]
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {//创建一个头节点ListNode head(0);ListNode *current = &head;// 新的进位int carry = 0;//遍历链表while (l1 || l2){//获取当前节点的值 如果为空就是0 int val1 = (l1 != nullptr) ? l1->val : 0;int val2 = (l2 != nullptr) ? l2->val : 0;//    计算当前位的和以及新的进位int sum = val1 + val2 + carry;carry = sum / 10;sum %= 10;// 创建新链表存储 头插current->next = new ListNode{sum};current = current->next;// 移动两个老链表链表指针if (l1){l1 = l1->next;}if (l2){l2 = l2->next;}// 如果最后还有进位,添加一个新节点if(carry > 0){current -> next = new ListNode{carry};}}//返回结果链表的头节点(跳过虚拟头节点)return head.next;}
};

3.无重复字符的最长字串(滑动窗口)

给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。

示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

提示:

  • 0 <= s.length <= 5 * 104
  • s 由英文字母、数字、符号和空格组成
class Solution {
public:int lengthOfLongestSubstring(string s) {// 存储索引和字符unordered_map <char , int> hash_table;int start = 0; //索引的起始位置 也是滑动窗口开始位置int maxLength = 0;  // 长度//遍历字符串for(int end = 0; end < s.size(); ++end)//end是滑动窗口结束位置{//存储当前字符char current = s[end];// 如果字符已存在于哈希表中,且其索引不小于窗口起始位置,则移动窗口起始位置if(hash_table.find(current) != hash_table.end() && hash_table[current] >= start){start = hash_table[current] + 1;}//  更新字符索引hash_table[current] = end;// 更新长度maxLength = max(maxLength,  end - start  + 1);}return maxLength;}
};

4.寻找两个正序数组的中位数(二分查找)

给定两个大小分别为 mn 的正序(从小到大)数组 nums1nums2。请你找出并返回这两个正序数组的 中位数

算法的时间复杂度应该为 O(log (m+n))

示例 1:

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2

示例 2:

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

思路:

算法的时间复杂度应该为 O(log (m+n)) 二分查找

1.使用分割线吧两个数组分割成两部分**,左右元素个数相等或者线左边元素的个数比右边个数多1个,线左边的所有元素的数值<= 右边的所有元素的数值**,中位数就与红线两侧单词元素有关,确定这条红线的位置使用二分查找

2.线左边的所有元素的数值<= 右边的所有元素的数值意味着第一个数组在分割线左边的最大值小于第二个数组在分割线右边的最小值,第二个数组在分割线左边的最大值小于第一个数组在分割线右边的最小值

在这里插入图片描述

在这里插入图片描述

分割线应该是这样

在这里插入图片描述

在这里插入图片描述

分割线应该是这样

可能出现极端的情况

在这里插入图片描述

在这里插入图片描述

class Solution {
public:double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {// 算法的时间复杂度应该为 O(log (m+n)) 二分查找  使用分割线吧两个数组分割成两部分,左右元素个数相等或者线左边元素的个数比右边个数多1个,线左边的所有元素的数值<= 右边的所有元素的数值// 确保nums1是小的数组if(nums1.size() >  nums2.size() ){return findMedianSortedArrays(nums2 ,nums1);}//长度int m = nums1.size();int n = nums2.size();// 中间位置 分割线左侧元素数int middle = (m + n + 1) / 2 ;//+1防止单数//在 nums1区间[0,m ]里面查找恰当的分割线// 使得nums[i - 1] <= num2[j] && nums[j - 1] <= nums[i] 这就是第一个数组在分割线左边的最大值小于第二个数组在分割线右边的最小值,第二个数组在分割线左边的最大值小于第一个数组在分割线右边的最小值
//     - 1表示在分割线左边int left = 0;int right = m;while(left < right){int i = left + (right - left + 1) / 2;//left 和right的中间位置 基数int j = middle - i; //分割线在第二个数组左边的元素if(nums1[i - 1] > nums2[j])//分割线在第一个数组左边的元素大于第二个数组在分割线右边的元素// 分割线靠右,分割线应该在i 的左边(无i){// 下一轮搜索的区间 【left, i- 1】right = i - 1;}else{// 下一轮搜索的区间 【i, right】left = i;}}// 找到nums[i - 1] <= num2[j]int i = left;int j=  middle - i;// 处理一些防止数组越界int numS1LeftMax = (i == 0) ? INT_MIN : nums1[i - 1];int numS1RightMin = (i == m) ? INT_MAX : nums1[i];int numS2LeftMax = (j == 0) ? INT_MIN : nums2[j - 1];int numS2RightMin = (j == n) ? INT_MAX : nums2[j];if((m + n) % 2 == 1)return  std::max(numS1LeftMax, numS2LeftMax);else return (max(numS1LeftMax, numS2LeftMax) + min(numS1RightMin, numS2RightMin)) / 2.0;}
};

相关文章:

  • 每日算法刷题Day10 5.19:leetcode不定长滑动窗口求最长/最大4道题,结束定长滑动窗口,用时1h
  • 大模型的开发应用(三):基于LlaMAFactory的LoRA微调(上)
  • CSS之box-sizing、图片模糊、计算盒子宽度clac、(重点含小米、进度条案例)过渡
  • 再议AOI算法
  • 谈谈mysql的日志的用途
  • Google精准狙击OpenAI Codex,发布AI编程助手Jules!
  • Kubernetes在线练习平台深度对比:KillerCoda与Play with Kubernetes
  • Rofin PowerLine E Air维护和集成手侧激光Maintenance and Integration Manual
  • 本地ip如何映射到外网?借助端口映射软件把内网地址给别人用
  • Python 包管理工具核心指令uv sync解析
  • 学习STC51单片机08(芯片为STC89C52RC)
  • 五、central cache的设计
  • unity XCharts插件生成曲线图在UICanvas中
  • TrollStore(巨魔商店)的由来介绍
  • 山东大学计算机图形学期末复习完结篇上——24历年题
  • CAU数据库class3 关系型数据库基础
  • 2001-2023年上市公司管理讨论与分析文本数据(MDA文本数据)
  • 【算法】定长滑动窗口5.20
  • 十五、面向对象底层逻辑-BeanDefinitionRegistryPostProcessor接口设计
  • 瀚高安全版4.5.8/4.5.9字符串默认按字节存储导致数据无法写入(APP)
  • 凤阳鼓楼瓦片脱落背后:涉事公司十年前曾因违规施工致文保建筑被烧毁
  • 上海地铁:9号线因雨天打滑,佘山往九亭方向部分列车限速运行
  • 财政部:4月份中央收入增长1.6%,今年以来首月实现正增长
  • 每日475.52元!最高检公布最新侵犯公民人身自由的赔偿金标准
  • 牛市早报|年内首次存款利率下调启动,5月LPR今公布
  • 体坛联播|利物浦三轮不胜,孙颖莎/王楚钦晋级混双八强