LeetCode刷题记199-Two Pointers(双指针)

287. 寻找重复数
再做一遍!!!

class Solution {
    public int findDuplicate(int[] nums) {
        int slow = 0, fast = 0;
        do {
            slow = nums[slow];
            fast = nums[nums[fast]];
        } while (slow != fast);
        slow = 0;
        while (slow != fast) {
            slow = nums[slow];
            fast = nums[fast];
        }
        return slow;
    }
}

567. 字符串的排列

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        int[] numsOfS1 = new int[26];
        for (int i = 0; i < s1.length(); i ++) {
            numsOfS1[s1.charAt(i) - 'a'] ++;
        }
        int[] numsOfS2 = new int[26];
        int i = 0;
        int j = 0;
        while (j < s2.length()) {
            int id = s2.charAt(j) - 'a';
            if (numsOfS1[id] == 0) {
                while (i <= j) {
                    numsOfS2[s2.charAt(i) - 'a'] --;
                    i ++;
                }
                j ++;
                continue;
            }
            if (numsOfS2[id] == numsOfS1[id]) {
                while(true) {
                    numsOfS2[s2.charAt(i) - 'a'] --;
                    if (s2.charAt(i) - 'a' == id) {
                        i ++;
                        break;
                    }
                    i ++;
                } 
                numsOfS2[id] ++;
                j ++;
                if (j - i == s1.length()) return true;
            } else if (numsOfS2[id] < numsOfS1[id]) {
                numsOfS2[id] ++;
                j ++;
                if (j - i == s1.length()) return true;
            }
        }
        return false;
    }
}

632. 最小区间

class Solution {
    public int[] smallestRange(List<List<Integer>> nums) {
        if (nums.size() == 1) return new int[] {nums.get(0).get(0), nums.get(0).get(0)};
        Collections.sort(nums, new Comparator<List<Integer>>(){
            @Override
            public int compare(List<Integer> a, List<Integer> b) {
                return a.get(0) - b.get(0);
            }
        });  // 开头的数字小的排在前面

        int ans1 = 0, ans2 = Integer.MAX_VALUE;
        int[] iOfCur = new int[nums.size()];  // 每一个数组开始的指针位置
        
        int _min = Integer.MAX_VALUE;  // 记录每个数组最大值的最小值
        for (List<Integer> i: nums) {
            _min = Math.min(_min, i.get(i.size() - 1));
        }

        int min = nums.get(0).get(0);
        int max = min;
        for (int i = 0; i < nums.get(0).size(); i ++) {
            min = Math.min(nums.get(0).get(i), _min);
            max = Math.max(nums.get(0).get(i), max);
        
            for (int j = 1; j < nums.size(); j ++) {
                List<Integer> cur = nums.get(j);
                int tmp = cur.get(iOfCur[j]);
                if (tmp > max) {
                    max = tmp;
                } else if (tmp < min) {
                    if (iOfCur[j] + 1 == cur.size()) {
                        min = tmp;
                    }
                    while (iOfCur[j] + 1 < cur.size()) {
                        int tmpNext = cur.get(iOfCur[j] + 1);
                        if (tmpNext < min) {
                            iOfCur[j] += 1;
                            if (iOfCur[j] + 1 == cur.size()) {
                                min = tmpNext;
                                break;
                            }
                        } else {
                            if (tmpNext <= max) {
                                iOfCur[j] += 1;
                            } else {
                                if (tmpNext - max >= min - tmp) {
                                    min = tmp;
                                } else {
                                    max = tmpNext;
                                    iOfCur[j] += 1;
                                }
                            }
                            break;
                        }
                        tmp = tmpNext;
                    }
                }
            }
            if (max - min < ans2 - ans1) {
                ans2 = max;
                ans1 = min;
            }
        }
        return new int[]{ans1, ans2};
    }
}

1610. 可见点的最大数目
做了两小时27分钟,一方面是因为不专心,一方面没有想好就开始敲代码了,我简直无语了。。。

class Solution {
    public double getAngle(int x, int y) {
        if (x == 0 && y > 0) return Math.PI / 2;
        if (x == 0 && y < 0) return Math.PI * 1.5;
        if (y == 0 && x > 0) return 0;
        if (y == 0 && x < 0) return Math.PI;
        if (x > 0 && y > 0) return Math.atan2(y, x);
        if (x > 0 && y < 0) return 2 * Math.PI - Math.atan2(-y, x);
        if (x < 0 && y > 0) return Math.PI - Math.atan2(y, -x);
        if (x < 0 && y < 0) return Math.atan2(-y, -x) + Math.PI;
        return 0;
    }
    public int visiblePoints(List<List<Integer>> points, int angle, List<Integer> location) {
        // 把location的位置作为原点(0,0)
        int ans = 0;
        List<Double> angles = new ArrayList<Double>();
        for (int i = 0; i < points.size(); i ++) {
            if (points.get(i).get(0) == location.get(0) && points.get(i).get(1) == location.get(1)) {
                ans ++;
                continue;
            }
            angles.add(Double.valueOf(getAngle(points.get(i).get(0) - location.get(0), points.get(i).get(1) - location.get(1))));
        }
        if (angles.size() == 0) return ans;

        Collections.sort(angles, new Comparator<Double>() {
            @Override
            public int compare(Double a, Double b) {
                if (a - b < 0) return -1;
                else if (a - b > 0) return 1;
                return 0;   // 不添加这个返回0,可能导致异常java.lang.IllegalArgumentException
            }
        });
        double _angle = angle * Math.PI / 180.0;
        int i = 0;
        int j = 0;
        int k = -1;  // 从第二轮开始
        double low = angles.get(0);
        double up = _angle + low;
        int curNum = 0;
        int maxNum = 0;
        while (j < angles.size()) {
            double curAngle = angles.get(j);
            if (curAngle >= low && curAngle <= up) {
                curNum ++;
            } else {
                maxNum = Math.max(maxNum, curNum);
                while (i <= j) {
                    i ++;
                    double iAngle = angles.get(i);
                    low = iAngle;
                    up = low + _angle;
                    if (curAngle >= low && curAngle <= up) {
                        if (up > Math.PI * 2) {
                            while (true) {
                                k ++;
                                double kAngle = angles.get(k);
                                if (kAngle <= up - Math.PI * 2) curNum ++;
                                else {
                                    k --;
                                    break;
                                }
                            }
                        }
                        break;
                    }
                    curNum --;
                }
                if (curAngle < low || curAngle > up) {
                    curNum = 1;
                    i --;
                } 
            }
            j ++;
        }
        maxNum = Math.max(maxNum, curNum);

        while (i < angles.size()) {
            low = angles.get(i);
            up = low + _angle;
            k ++;
            double kAngle = angles.get(k);
            while (kAngle <= up - Math.PI * 2) {
                curNum ++;
                k ++;
                kAngle = angles.get(k);
            }
            k --;
            i ++;
            maxNum = Math.max(maxNum, curNum);
            curNum --;
        }
        ans += Math.max(maxNum, curNum);
        return ans;
    }
}

349. 两个数组的交集

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int i = 0; 
        int j = 0;
        Set<Integer> set = new HashSet<Integer>();
        while (i < nums1.length && j < nums2.length) {
            if (nums1[i] == nums2[j]) {
                set.add(nums1[i]);
                i ++;
                j ++;
            } else if (nums1[i] < nums2[j]) {
                i ++;
            } else {
                j ++;
            }
        }
        int[] ans = new int[set.size()];
        int id = 0;
        for (Integer k : set) {
            ans[id ++] = k;
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值