文章目录

  • 1、两数之和
  • 2、两数相加
  • 3、无重复字符的最长子串
  • 4、最长回文子串
  • 5、盛最多水的容器
  • 6、删除链表的倒数第 N 个结点
  • 7、Day 2 【未完待续】

1、两数之和

通往【LeetCode - 两数之和】的任意门

解法一:暴力解
采用两层for循环,第一次层循环选取第一个数,第二次循环选取第二个数,第二层循环找到符合的数则直接返回结果。
时间复杂度:O(n^2)
空间复杂度:O(1)

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

解法二:使用map
第一次遍历数组,初始化map,判断map是否存在key为nums[i]的键值对,不存在则将(nums[i], i)插入map中,存在则继续下一轮循环。
第二次遍历数组,若能够在map中找到key为target - nums[i],且value != i的键值对,则返回结果。
时间复杂度:O(n)
空间复杂度:O(n)

 vector<int> twoSum(vector<int>& nums, int target) {vector<int> res;// 定义map并初始化map<int, int> numMap; for (int i = 0; i < nums.size(); i ++) {if (numMap.find(nums[i]) == numMap.end()) {numMap.insert(pair<int, int>(nums[i], i));}}for (int i = 0; i < nums.size(); i ++) {map<int, int>::iterator it = numMap.find(target - nums[i]);// 注意第二个条件,保证两个下标不同if (it != numMap.end() && (*it).second != i) {res.push_back(i);res.push_back((*it).second);return res;}}return res;}

2、两数相加

通往【LeetCode - 两数相加】的任意门

两个链表相加,主要要解决两个链表长度不一致以及进位的问题。
长度不一致问题:可分为三种情况,第一,两个链表都还有未处理的节点;第二,只有链表一还有未处理的节点;第三,只有链表二还有未处理的节点。
进位问题:设置一个变量标记低一位的运算是否有进位。

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {// 判断边界条件if (l1 == NULL || l2 == NULL) {return l1 == NULL ? l2 : l1;}// 创建存储结果链表的虚拟头结点ListNode *head = new ListNode(-1, NULL);ListNode *cur = head;// 前一位的进位int addBit = 0;// l1与l2都还有未计算的结点while (l1 != NULL && l2 != NULL) {int res = l1->val + l2->val + addBit;if (res >= 10) {addBit = 1;cur->next = new ListNode(res - 10, NULL);} else {addBit = 0;cur->next = new ListNode(res, NULL);}cur = cur->next;l1 = l1->next;l2 = l2->next;}// 仅l1还有未计算的结点while (l1 != NULL) {int res = l1->val + addBit;if (res >= 10) {addBit = 1;cur->next = new ListNode(res - 10, NULL);} else {addBit = 0;cur->next = new ListNode(res, NULL);}cur = cur->next;l1 = l1->next;}// 仅l2还有未计算的结点while (l2 != NULL) {int res = l2->val + addBit;if (res >= 10) {addBit = 1;cur->next = new ListNode(res - 10, NULL);} else {addBit = 0;cur->next = new ListNode(res, NULL);}cur = cur->next;l2 = l2->next;}// 判断最后是否有进位if (addBit == 1) {cur->next = new ListNode(1, NULL);}ListNode* temp = head->next;// 释放虚拟头结点head->next = NULL;delete head;head = NULL;return temp;
}

3、无重复字符的最长子串

通往【LeetCode - 无重复字符的最长子串】的任意门

利用map缓存当前无重复字符的字符及其对应位置,采用滑动窗口的思想求出无重复字符子串的最大长度

int lengthOfLongestSubstring(string s) {if (s == "") {return 0;}// 将字符串转化为char数组char buf[s.size()];s.copy(buf, s.size());// 用于记录当前子串的字符及对应下标map<char, int> charMap;// 用于记录无重复字符的子串的最大值int max = 0;// 当前子串的开始与结束位置,[left, right)int left = 0, right = 0;// 利用滑动窗口的思想求无重复字符的最长子串while (right < s.size()) {// 判断是否出现重复字符map<char, int>::iterator it = charMap.find(buf[right]);if (it != charMap.end()) {// 存在则将left 到 前一次出现该字符的位置 的字符从map中删除int val = (*it).second;for (int i = left; i <= val; i++) {charMap.erase(buf[i]);}// 更新max与leftmax = max > (right - left) ? max : (right - left);left = val + 1;charMap.insert(pair<char,int>(buf[right], right));} else {charMap.insert(pair<char,int>(buf[right], right));}right ++;}// 最后判断是否需要更新maxmax = max > (right - left) ? max : (right - left);        return max;
}

4、最长回文子串

通往【LeetCode - 最长回文子串】的任意门

解法一:暴力枚举

string longestPalindrome(string s) {// 处理边界条件if (s.size() < 2) {return s;}// 将字符串转化为char数组char buf[s.size()];s.copy(buf, s.size());// 最长回文子串的长度,起始位置,结束位置int maxLen = 0;// 最长回文子串buf[start, end]int start = 0, end = -1;// 暴力枚举,枚举每个位置的字符都作为起始位置和结束位置for(int i = 0; i < s.size(); i ++) {for(int j = i; j < s.size(); j ++) {// 先判断当前子串是否大于最大长度// 若当前子串长度小于最大长度,则不需要进行是否为回文串的判断if ((j - i + 1) > maxLen && palindrome(buf, i, j)) {maxLen = j - i + 1;start = i;end = j;}}}return s.substr(start, maxLen);
}// 判断buf[low, high]是否为回文子串
bool palindrome(char *buf, int low, int high) {while (low < high) {if (buf[low] != buf[high]) {return false;}low ++;high --;} return true;}

解法二:中心扩散法

string longestPalindrome(string s) {  // 处理边界条件 if (s.size() < 2) {return s;}// 将字符串转化为char数组char buf[s.size()];s.copy(buf, s.size());// 最大回文子串的长度,起始位置,结束位置int maxLen = 1;int start = 0, end = 0;// 遍历字符,以每个字符作为回文串的中心进行扩展int low = 0, high = 0;for(int i = 0; i < s.size(); i ++) {low = i;high = i;// 若中心字符左右相邻两边存在与其相同的字符,则将这些相同的字符一起作为扩散的中心while (low - 1 >= 0 && buf[i] == buf[low - 1]) low --;while (high + 1 < s.size() && buf[i] == buf[high + 1]) high ++;// 两边扩散while (low > 0 && high < s.size() - 1 && buf[low - 1] == buf[high + 1]) {low --;high ++;}// 判断是否更新最大回文串信息if (high - low + 1 > maxLen) {maxLen = high - low + 1;start = low;end = high;}}return s.substr(start, maxLen);
}

5、盛最多水的容器

通往【LeetCode - 盛最多水的容器】的任意门

解法:贪心算法 - 双指针
可以将容积抽象为面积大小,因此决定容积大小的因素有两个:第一,两根柱子之间的距离;第二,构成容器的两根柱子的高度的较小值。
因为容积大小由两个因素共同决定,我们无法直接使用贪心算法。如果要使用贪心算法,那么我们必须让遍历过程中有其中一个因素是从最优逐渐衰减的。首先想到的是排序,但由于排序会打乱柱子之间的顺序,从而影响到因素一。那么,我们应该让遍历过程中柱子之间的距离是从大到小的,因此我们初始化两个指针,分别指向数组头部和尾部。
最后需要解决的是,在遍历过程中如何贪心柱子高度才能使结果最优。由于柱子之间的距离是逐渐减小的,头尾指针中的较小者不可能再次成为答案,所以我们可以让高度较小的指针移动,直至头尾指针相遇,则得出最优解。
时间复杂度:O(n)
空间复杂度:O(1)

int maxArea(vector<int>& height) {int max = 0, l = 0, r = height.size() - 1;int maxHeight = 0;while (l < r) {// 计算当前的容积,并判断是否需要更新容积最大值int min = height[l] > height[r] ? height[r] : height[l];int area = min * (r - l);if (area > max) {max = area;maxHeight = min;}// 高度较小者移动if (height[l] < height[r]) {l ++;} else {r --;}}return max;
}

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

通往【LeetCode - 删除链表的倒数第 N 个结点】的任意门

解法:双指针
在单链表中,假定要删除倒数第2个结点,我们需要其前驱结点,即倒数第3个结点。
由于删除的结点有可能是头结点,为方便统一处理,我们设置虚拟头结点(-1)
假定链表为[1, 2, 3, 4, 5],需要删除倒数第2个结点

  1. 第一步:最初p,q指针都指向虚拟头结点
    p↓ ↓q
    (-1) -> 1 -> 2 -> 3 -> 4 -> NULL
  2. 第二步:先让指针q向后移动 2 + 1 次
    p↓ ↓q
    (-1) -> 1 -> 2 -> 3 -> 4 -> NULL
  3. 第三步:指针p,q同步向后移动,当q = NULL时则结束循环
    p↓ ↓q
    (-1) -> 1 -> 2 -> 3 -> 4 -> NULL
  4. 第四步:删除倒数第2个结点,返回 虚拟头结点->next
    p->next = p->next->next;
    return 虚拟头结点->next;

时间复杂度:O(n)
空间复杂度:O(1)

ListNode* removeNthFromEnd(ListNode* head, int n) {// 创建虚拟头结点,并将p,q指针都指向虚拟头结点ListNode* p = new ListNode(-1, head);ListNode* h = p;ListNode* q = p;while (n > -1) {q = q->next;n --;}while (q != NULL) {q = q->next;p = p->next;}// 删除并释放倒数第n个结点ListNode* temp = p->next;p->next = p->next->next;delete temp;temp = NULL;// 删除并释放虚拟头结点temp = h->next;delete h;h = NULL;return temp;
}

7、Day 2 【未完待续】

LeetCode热题100道相关推荐

  1. Leecode31. 下一个排列——Leecode大厂热题100道系列

    我是小张同学,立志用最简洁的代码做最高效的表达 以下是我个人做的题解,每个题都尽量囊括了所有解法,并做到了最优解,欢迎大家收藏!留言! 传送门-->Leecode大厂热题100道系列题解 问题描 ...

  2. Leecode22. 括号生成——Leecode大厂热题100道系列

    我是小张同学,立志用最简洁的代码做最高效的表达 以下是我个人做的题解,每个题都尽量囊括了所有解法,并做到了最优解,欢迎大家收藏!留言! 传送门-->Leecode大厂热题100道系列题解 问题描 ...

  3. Leecode20. 有效的括号——Leecode大厂热题100道系列

    我是小张同学,立志用最简洁的代码做最高效的表达 以下是我个人做的题解,每个题都尽量囊括了所有解法,并做到了最优解,欢迎大家收藏!留言! 传送门-->Leecode大厂热题100道系列题解 问题描 ...

  4. Leecode 21. 合并两个有序链表——Leecode大厂热题100道系列

    我是小张同学,立志用最简洁的代码做最高效的表达 以下是我个人做的题解,每个题都尽量囊括了所有解法,并做到了最优解,欢迎大家收藏!留言! 传送门-->Leecode大厂热题100道系列题解 题目描 ...

  5. Leecode19. 删除链表的倒数第 N 个结点——Leecode大厂热题100道系列

    我是小张同学,立志用最简洁的代码做最高效的表达 以下是我个人做的题解,每个题都尽量囊括了所有解法,并做到了最优解,欢迎大家收藏!留言! 传送门-->Leecode大厂热题100道系列题解 题目描 ...

  6. Leecode17. 电话号码的字母组合——Leecode大厂热题100道系列

    我是小张同学,立志用最简洁的代码做最高效的表达 以下是我个人做的题解,每个题都尽量囊括了所有解法,并做到了最优解,欢迎大家收藏!留言! 传送门-->Leecode大厂热题100道系列题解 问题描 ...

  7. Leecode15. 三数之和——Leecode大厂热题100道系列

    我是小张同学,立志用最简洁的代码做最高效的表达 以下是我个人做的题解,每个题都尽量囊括了所有解法,并做到了最优解,欢迎大家收藏!留言! 传送门-->Leecode大厂热题100道系列题解 问题描 ...

  8. Leecode11. 盛最多水的容器——Leecode大厂热题100道系列

    我是小张同学,立志用最简洁的代码做最高效的表达 以下是我个人做的题解,每个题都尽量囊括了所有解法,并做到了最优解,欢迎大家收藏!留言! 传送门-->Leecode大厂热题100道系列题解 问题描 ...

  9. Leecode07. 整数反转——Leecode大厂热题100道系列

    我是小张同学,立志用最简洁的代码做最高效的表达 以下是我个人做的题解,每个题都尽量囊括了所有解法,并做到了最优解,欢迎大家收藏!留言! 传送门-->Leecode大厂热题100道系列题解 问题描 ...

最新文章

  1. jenkins环境搭建
  2. [BZOJ 2555] SubString
  3. C和指针之多维数组一行存满后会轮到下一行
  4. fatal: remote origin already exists. (远程来源已经存在 解决办法)
  5. 2018年山西省环境空气质量综合指数平均下降10.8%
  6. 吴裕雄 python 机器学习——人工神经网络与原始感知机模型
  7. kaggle泰坦尼克
  8. 《我的团长我的团》 - 观后感
  9. iphone通过iTunes12.7怎么设置铃声
  10. Sick编码器CanOpen通信
  11. 求图像边界点坐标c语言,三、Windows图像处理—画点和线(边框函数)
  12. 利用html标记制作静态网页,使用HTML制作网页《静态网页制作》.ppt
  13. 微信小程序海报功能(canvas)- - -附效果图
  14. coTurn 运行在Windows平台的方法
  15. 校园综合服务平台-微信小程序
  16. Forward warping and backward warping
  17. html调色盘字符,油画基础知识:调色盘最详细讲解
  18. php 微信平台,【php】微信公众平台
  19. 纳斯达克的区块链野望
  20. 520送对象什么礼物最好?精选4款好用的电容笔

热门文章

  1. 【易语言助手插件】IDE 鼠标手势1.2 原汁原味移植浏览器手势
  2. VUE项目引入微信JSSDK 实现微信自定义分享
  3. 试看5分钟视频python_不会Python吗?几分钟看完资深程序员给你的Python入门指南...
  4. Anchor-based和Anchor-free优缺点对比
  5. 用php编写多项选择题_php 多选框问题(类似一道多选题)多选题的答案 以及正确答案都记录到数据库里了,读取修改问题...
  6. 通过站点优化记录规划书
  7. qq令牌64位密钥提取_QQ令牌工具 活令牌查询动态密码(大哥牌)
  8. 在数据库中,视图有什么用?什么时候需要用到视图?
  9. jQuery选择器(二)
  10. [题集]Lecture 4. Leftist Heaps and Skew Heaps