算法-双指针

两个指针解决一道题-技巧

普通双指针:两个指针往同一个方向移动

对撞双指针:两个指针面对面移动  (遇到有序情况下可以考虑)两数之和

快慢双指针:慢指针+快指针 环形链表


a=[1,4,5,7,9]

两个数相加=12

两个数不能相同

用普通双指针从头遍历时间复杂度为O(N^2)

对撞双指针 此时时间复杂度为O(N)

a=[1,4,5,7,9] 两个数相加=12,两个数不能相同

i指第一个 j指最后一个

a[i]+a[j]=10 比12小,因为这是有序数组

所有要i指针需要往右移动,移动之后a[i]+a[j]=13比12大了,所以需要将j指针向左移动

a[i]+a[j]=11<12  i指针向左移动,a[i]+a[j]=12

找到了对应的i和j 

快慢双指针

环形链表

s指针第一次移动一次,f指针一次移动了两次

当s指针和f指针遇上的时候,说明这个链表是一个环形链表

力扣141

算法-双指针_第1张图片

 

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        if(head==null){
            return false;
        }
        while(fast.next!=null&&fast!=null&&fast.next.next!=null){
        slow =slow.next;
        fast = fast.next.next;
        if(slow==fast){
             return true;
        }
        }
     return false;
    }
}

思路:定义一个快指针,一个慢指针,当为链表空的时候返回false,当fast  fast.next  fast.next.next 都不为空的时候(把fast 和fast.next放上 是考虑只有一个数 或 只有两个数的情况,如果不成环的话就会报错),快指针移动两个,满指针移动一个,当快指针和慢指针相遇的时候停止并return true ,如果没进入环就会在指针走到末尾的时候退出循环return false

力扣881

算法-双指针_第2张图片

 思路:因为是两数之和的运算,想到对撞指针的方法,但对撞指针只能运用在有序的数组上面,所以这里要对数组进行排序,把数组从小到大排序,这里一艘船最多坐两个,最胖的如果跟最轻的一起坐都超重的话,就只能自己坐一艘船,在最瘦的设一个i指针,在最胖的设一个j指针,people[i]+people[j]>limit   j自己走,  j向左移动一个, people[i]+people[j]<=limit,

i和j一起走,i向右移动一个,j向左移动一个,这些都是在i

class Solution {
    public int numRescueBoats(int[] people, int limit) {
        if (people.length == 0) {
            return 0;
        }

        Arrays.sort(people);

        int i = 0;
        int j = people.length - 1;
        int count = 0;

        while (i < j) {
            if ((people[i] + people[j]) <= limit) {
                i++;
                j--;
                count++;
            } else {
                j--;
                count++;
            }
        }

        if (i == j) {
            count++;
        }

        return count;
    }
}

你可能感兴趣的:(算法,算法,c语言,散列表)