代码随想录 - Day16 - 双指针法

代码随想录 - Day16 - 双指针法

151. 反转字符串中的单词

strip()用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
str.strip([chars])

  • chars – 移除字符串头尾指定的字符序列
  • 返回移除字符串头尾指定的字符生成的新字符串

法1

 # 删除前后空白
s = s.strip()
# 反转整个字符串
s = s[::-1]
# 将字符串拆分为单词,并反转每个单词
s = ' '.join(word[::-1] for word in s.split())
return s

法2

# 将字符串拆分为单词,即转换成列表类型
words = s.split()

# 反转单词
left, right = 0, len(words) - 1
while left < right:
    words[left], words[right] = words[right], words[left]
    left += 1
    right -= 1

# 将列表转换成字符串
return " ".join(words)


206. 反转链表

画图理解能好想一点

prev, curr = None, head
# T O(n) M O(1)
while curr:
    nxt = curr.next
    curr.next = prev
    prev = curr
    curr = nxt
return prev

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

本来想试试不用虚拟头结点,但最终发现如果不用虚拟头结点,就无法处理head = [1], n = 1的情况

# 创建一个虚拟节点,并将其下一个指针设置为链表的头部
dummy_head = ListNode(0, head)

slow = dummy_head
quick = dummy_head
while n >= 0:
    quick = quick.next
    n -= 1
while quick:
    quick = quick.next
    slow = slow.next
slow.next = slow.next.next
return dummy_head.next

面试题 02.07. 链表相交

curA, curB = headA, headB
cntA, cntB = 0, 0
# 计算两个链表的长度
while curA:
    curA = curA.next
    cntA += 1
while curB:
    curB = curB.next
    cntB += 1
# 计算长度差
step = abs(cntA - cntB)
# 更新两节点位置
curA, curB = headA, headB
if cntA > cntB:
    while step > 0:
        curA = curA.next
        step -= 1
elif cntA < cntB:
    while step > 0:
        curB = curB.next
        step -= 1
# 比较节点
while curA:
    if curA == curB:    # 若相等则返回
        return curA
    # 前进
    curA = curA.next
    curB = curB.next
# 没有相交的点,返回None
return None

142. 环形链表 II

slow, fast = head, head
while fast != None and fast.next != None:
    slow = slow.next        # 慢指针一次走一个
    fast = fast.next.next   # 快指针一次走两个
    if slow == fast:        # 若相等则成环
        i1 = fast           # 找环的入口
        i2 = head
        while i1 != i2:
            i1 = i1.next
            i2 = i2.next
        return i2
return None

15. 三数之和

nums.sort()     # 给序列排序
res = []

for position in range(len(nums)):   
    if nums[position] > 0:          # 排除特殊情况
        break
    # 去重
    if position > 0 and nums[position] == nums[position - 1]:
        continue
    left = position + 1
    right = len(nums) - 1
    while right > left:
        if nums[position] + nums[left] + nums[right] > 0:
            right -= 1
        elif nums[position] + nums[left] + nums[right] < 0:
            left += 1
        else:
            res.append([nums[position], nums[left], nums[right]])
            # 去重
            while right > left and nums[right] == nums[right - 1]:
                right -= 1
            while right > left and nums[left] == nums[left + 1]:
                left += 1
            right -= 1
            left += 1
return res

18. 四数之和

三数之和是以0为标准,四数之和要考虑到target不确定,所以判断条件要改,要注意target

res = []
nums.sort()

for k in range(len(nums)):
    # 剪枝处理
    if nums[k] > target and nums[k] >= 0:
        break
    # 对nums去重
    if k > 0 and nums[k] == nums[k - 1]:
        continue
    for i in range(k + 1, len(nums)):
        # 剪枝处理
        if nums[k] > target and nums[k] >= 0:
            break
        # 对nums[i]去重
        if i > k + 1 and nums[i] == nums[i - 1]:
            continue

        left = i + 1
        right = len(nums) - 1
        while right > left:
            if nums[k] + nums[i] + nums[left] + nums[right] > target:
                right -= 1
            elif nums[k] + nums[i] + nums[left] + nums[right] < target:
                left += 1
            else:
                res.append([nums[k], nums[i], nums[left], nums[right]])
                # 对nums[left]和nums[right]去重
                while right > left and nums[right] == nums[right - 1]:
                    right -= 1
                while right > left and nums[left] == nums[left + 1]:
                    left += 1
                right -= 1
                left += 1
return res

双指针应用

  • 移除数组元素
  • 字符传替换、填充、删除
  • 链表涉及查找/删除特定元素的问题
  • N数之和问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值