算法学习——双指针法

双指针法

  • 移除元素
  • 反转字符串
  • 替换数字
  • 翻转字符串里的单词
  • 翻转链表
  • 删除链表的倒数第N个节点
  • 链表相交
  • 环形链表II
  • 三数之和
  • 四数之和
  • 总结
    • 数组篇
    • 字符串篇
    • 链表篇
    • N数之和篇

移除元素

力扣题目链接

此题做法在数组章节中。

反转字符串

力扣题目链接

此题做法在字符串章节中。

替换数字

卡码网题目链接

此题做法在字符串章节中。

翻转字符串里的单词

力扣题目链接

此题做法在字符串章节中。

翻转链表

力扣题目链接

此题做法在链表章节中。

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

力扣题目链接

此题做法在链表章节中。

链表相交

力扣题目链接

此题做法在链表章节中。

环形链表II

力扣题目链接

此题做法在链表章节中。

三数之和

力扣题目链接

此题做法在哈希表章节中。

四数之和

力扣题目链接

此题做法在哈希表章节中。

总结

数组篇

原地移除数组上的元素,不能真正的删除,只能覆盖。

一些同学可能会写出如下代码(伪代码):

for (int i = 0; i < array.size(); i++) {
    if (array[i] == target) {
        array.erase(i);
    }
}

这个代码看上去好像是O(n)的时间复杂度,其实是O(n^2)的时间复杂度,因为erase操作也是O(n)的操作。

所以此时使用双指针法才展现出效率的优势:通过两个指针在一个for循环下完成两个for循环的工作。

字符串篇

反转字符串,注意这里强调要原地反转,要不然就失去了题目的意义。
使用双指针法,定义两个指针(也可以说是索引下标),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素,时间复杂度是O(n)。

在替换数字中介绍使用双指针填充字符串的方法,如果想把这道题目做到极致,就不要用额外的辅助空间。
思路就是首先扩充数组到每个数字替换成number之后的大小。然后双指针从后向前替换数字。
其实很多数组(字符串)填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。

在删除冗余空格的过程中,如果不注意代码效率,很容易写成了O(n^2)的时间复杂度。其实使用双指针法O(n)就可以搞定。
主要还是erase用的比较随意,一定要注意for循环下用erase的情况,一般可以用双指针写效率更高。

链表篇

使用双指针法来翻转链表,只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表。

在链表中求环,应该是双指针在链表里最经典的应用。
使用快慢指针(双指针法),分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。
找到环的入口,其实需要点简单的数学推理。

N数之和篇

去重的过程不好处理,有很多小细节,如果在面试中很难想到位。
通过前后两个指针不算向中间逼近,在一个for循环下完成两个for循环的工作。

对于三数之和使用双指针法就是将原本暴力O(n3)的解法,降为O(n2)的解法,四数之和的双指针解法就是将原本暴力O(n4)的解法,降为O(n3)的解法。
同样的道理,五数之和,n数之和都是在这个基础上累加。

你可能感兴趣的:(代码随想录算法学习,算法,学习)