九章算法笔记 7.两根指针 Two Pointers

大纲 cs3k.com

  1. 同向双指针
  2. 相向双指针
  3. Two Sum :3.1 大小• = target• <= target • > target     3.2 去重• unique pairs    3.3 离得近• closest to target

    3.4 差

    • difference = target

  4. Partition• Quick Select• 分成两个部分• 分成三个部分
  5. Sort• 彩虹排序• 烙饼排序• (还有前面学的拓扑排序)• 一些你没听过的(但是面试会考的)排序算法

 

同向双指针Window Sum 

cs3k.com

Given an array of n integer, and a moving window(size k), move the window at each iteration from the start of the array, find the sum of the element inside the window at each moving.

用prefix sum解,会用extra space

所以就挪一下,加新的,减旧的

同向双指针Move Zeroes

Given an array nums, write a function to move all 0’s to the end of it while maintaining the relative order of the non-zero elements.

用hash_set, 时间O(n), 快; 但是用extra space

用双指针, 类似于去重的问题,指针for一下,如果发现不是0,往前填

相向双指针Rotate String

Given a string and an offset, rotate string by offset. (rotate from left to right).

Given “abcdefg”.

offset=3 => “efgabcd”

做法:

abcd | efg => 两段分别反序

dcba | gfe => 整体反序

efgabcd

Two Sum

cs3k.com

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are NOT zero-based.

            TIME     SPACE
hash_set    O(n)     O(n)
sort+2p     O(nlogn) O(1)

sort+2pointers方法的指针:

l永远指向有机会成为二元数组里面小的那个数

r永远指向有机会成为二元数组里面大的那个数

Two Sum – Data structure design 

cs3k.com

Design and implement a TwoSum class. It should support the following operations: add and find.

add – Add the number to an internal data structure.

find – Find if there exists any pair of numbers which sum is equal to the value.

Example

add(1); add(3); add(5);

find(4) // return true

find(7) // return false

双指针要求是有序序列,因为不断再加入新的元素, 所以只能用trie树(平衡二叉树), 但是trie树又很慢.

所以就hash_set啦~

Two Sum – Unique pairs 

cs3k.com

Given an array of integers, find how many unique pairs in the array such that their sum is equal to a specific target number. Please return the number of pairs.

比如:

        1 1' 2 45 46 46'   target:92            
        l             r

不能开始去重, 后面去

在第一次做第一个1和最后一个46已经把所有和1和46相关的解找光了, 所以后面就直接跳过

3 Sum

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

            TIME     SPACE
hash_set    O(n^2)     O(n)
sort+2p     O(n^2)     O(1)

先排个序, 固定a, 在a的右面找b+c= -a

Triangle Count 

cs3k.com

Given an array of integers, how many three numbers can be found in the array, so that we can build an triangle whose three edges length is the three numbers that we find?

a…….b…….c…

如果a可以和b c组队,那么[a,b)都可以

所以固定b和c挨个挪a

统计所有方案需要O(n^3)

如果只需要方案的个数的话, 差不多O(n^2)

Two Sum – Closest to target

Given an array nums of n integers, find two integers in nums such that the sum is closest to a given number, target.

Return the difference between the sum of the two integers and the target.

记录一下difference就可以了

3 Sum Closest

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers.

You may assume that each input would have exactly one solution.

for循环其中一个, 另外两个做2 sum closest

Two Sum – Difference equals to target

Given an array of integers, find two numbers that their difference equals to a target value.

where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are NOT zero-based.

同向指针

Partition Array 

cs3k.com

Given an array nums of integers and an int k, partition the array (i.e move the elements in “nums”) such that:

All elements < k are moved to the left All elements >= k are moved to the right

Return the partitioning index, i.e the first index i nums[i] >= k.

有两种类型:

  1. 分左右

     

  2. 分左中右

左右两个指针l和r

l的意思: l-1及之前的部分是小于k的

并且从左往右找第一个不应该在左边的

r的意思: r+1及之后的部分是大于等于k的

从右往左找第一个不应该在右边的

public class Solution {
    /** *@param nums: The integer array you should partition *@param k: As description *return: The index after partition */ public int partitionArray(int[] nums, int k) { if(nums == null || nums.length == 0){ return 0; } int left = 0, right = nums.length - 1; while (left <= right) { while (left <= right && nums[left] < k) { left++; } while (left <= right && nums[right] >= k) { right--; } if (left <= right) { int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; left++; right--; } } return left; } }

Kth Smallest Numbers in Unsorted Array

cs3k.com

Find the kth smallest numbers in an unsorted integer array.

```java
class Solution {
    /*
     * @param k an integer
     * @param nums an integer array
     * @return kth smallest element
     */
    public int kthSmallest(int k, int[] nums) { // write your code here return quickSelect(nums, 0, nums.length - 1, k - 1); } public int quickSelect(int[] A, int start, int end , int k) { if (start == end) return A[start]; int left = start, right = end; int pivot = A[(start + end) / 2]; while (left <= right) { while (left <= right && A[left] < pivot) { left++; } while (left <= right && A[right] > pivot) { right--; } if (left <= right) { int temp = A[left]; A[left] = A[right]; A[right] = temp; left++; right--; } } if (right >= k && start <= right) return quickSelect(A, start, right, k); else if (left <= k && left <= end) return quickSelect(A, left, end, k); else return A[k]; } }; ```

Partition Array by Odd and Even

Partition an integers array into odd number first and even number second.

Interleaving Positive and Negative Numbers

cs3k.com

Given an array with positive and negative integers. Re-range it to interleaving with positive and negative integers.

Sort Letters by Case

Given a string which contains only letters. Sort it by lower case first and upper case second.

这三道题是类似的, 就是先把正的和负的分左右(奇数和偶数分左右), 再交替交换

其中要说明:

  1. 快排不是稳定排序, 1 1’ 2 可能变成 1’ 1 2

     

  2. merge sort归并是稳定排序, 但是需要额外O(n)的空间

Sort Colors

cs3k.com

Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

solution 1. 两次partition

分0 1 2 可以先把0和1 2 分开

再分开1 和2, 两次partition

solution 2. 三个指针

三个指针l, r, i

i指针, 从左到右

遇到0: i和l换, 左边扩大1

遇到2: i和r换, 右边扩大1

遇到0: 接着走,不做处理

public class Solution {
    public void sortColors(int[] a) { if (a == null || a.length <= 1) { return; } int pl = 0; int pr = a.length - 1; int i = 0; while (i <= pr) { if (a[i] == 0) { swap(a, pl, i); pl++; i++; } else if(a[i] == 1) { i++; } else { swap(a, pr, i); pr--; } } } private void swap(int[] a, int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } }

Sort Colors II

Given an array of n objects with k different colors (numbered from 1 to k), sort them so that objects of the same color are adjacent, with the colors in the order 1, 2, … k.

科普几个排序名词

rainbow sort: 彩虹排序

counting sort: 计数排序

radix sort: 基数排序

基于比较的排序, 最快只能nlogn

这道题时间复杂度:

k = n 是 nlogn

k = 1 是 n

k = 2 是 n

k = 3 是 2*n

所以只能nlogk了

带log的的, 怎么把k的问题变为2/k的问题, 及怎么把颜色范围缩小一半

enter image description here

other sort

睡眠排序

面条排序

猴子排序

ps: 写程序是规定一个事情, 后面不破坏这个事情

Quick Select

cs3k.com

kth largest element

用快排的话, 需要O(nlogn)的时间, 如果需要更快的话, 嗯…

class Solution {
    /*
     * @param k : description of k
     * @param nums : array of nums
     * @return: description of return
     */
    public int kthLargestElement(int k, int[] nums) { // write your code here if (nums == null || nums.length == 0) { return 0; } if (k <= 0) { return 0; } return helper(nums, 0, nums.length - 1, nums.length - k + 1); } public int helper(int[] nums, int l, int r, int k) { if (l == r) { return nums[l]; } int position = partition(nums, l, r); if (position + 1 == k) { return nums[position]; } else if (position + 1 < k) { return helper(nums, position + 1, r, k); } else { return helper(nums, l, position - 1, k); } } public int partition(int[] nums, int l, int r) { // 初始化左右指针和pivot int left = l, right = r; int pivot = nums[left]; // 进行partition while (left < right) { while (left < right && nums[right] >= pivot) { right--; } nums[left] = nums[right]; while (left < right && nums[left] <= pivot) {

转载于:https://www.cnblogs.com/jiuzhangsuanfa/p/9895661.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值