刷题记录|目标101题--双指针

写在前面

开个贴记录一下刷题的过程,目前参照leetcode101,目标101题,由于太久没写java了,也会涉及到一些java的基础用法,希望能和大家共勉吧~
已刷链接:

双指针


No.1 Two Sum II - Input Array Is Sorted

题目链接:https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/

设计到的算法:双指针
解题思路:左右各一个指针滑动既可
class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int i = 0, j = numbers.length - 1;
        while(numbers[i] + numbers[j] != target) {
            if (numbers[i] + numbers[j] < target) {
                i ++;
            } else {
                j --;
            }
        }
        int[] result = {++i,++j};
        return result;
    }
}

No.2 Merge Sorted Array

题目链接:https://leetcode.com/problems/merge-sorted-array/

涉及到的算法:双指针
解题思路:
从前往后的两个指针不可行因为会覆盖,那么考虑从后往前数两个指针,发现从后往前是work的

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int i = m - 1, j = n - 1, current = m + n - 1;
        while (i >= 0 && j >= 0) {
            if (nums1[i] > nums2[j]) {
                nums1[current--] = nums1[i--];
            } else {
                nums1[current--] = nums2[j--];
            }
        }
        while(i >= 0) {
            nums1[current--] = nums1[i--];
        }
        while(j >= 0) {
            nums1[current--] = nums2[j--];
        }
    }
}

No. 3 Linked List Cycle II

题目链接:https://leetcode.com/problems/linked-list-cycle-ii/

涉及到的算法:快慢指针
解题思路:快慢指针

快慢指针中如果用图表示就是将路径分为abc三段,a表示从链表头到成环点,b表示从环点到相遇处,c表示从相遇处到环点,其计算公式如下(图好丑TT)

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null) return null;
        ListNode fast = head;
        ListNode slow = head;
        while (fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                break;
            }
        }
        if (fast.next == null || fast.next.next == null) {
            return null;
        }
        fast = head;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
    
}

No.4 Minimum Window Substring

题目链接:https://leetcode.com/problems/minimum-window-substring/

涉及到的算法:滑动窗口
解题思路:
首先需要先遍历一遍string t,用数组记录下来他的character出现的次数。
用l和r指针遍历这个数组,在遍历时及时更新这个数组。
  • 如果r滑过了则将对应character次数--,
  • 如果l滑过了,此时如果只是单一的character数组,我们在看到l指针指向的字符对应在character数组中的计数为0时,无法区分是这个字符从未在string t中出现过,可以划走还是出现过但是正好被指针r覆盖,所以展示的0,此时不能划走,故引入数组flag[]在首次遍历时同时记录数组character和数组flag
  • 需要将string s从头到位遍历一遍,存储一个最小值,中间每次满足条件时将值与最小值对比,如果比最小值还要小更新最小值

  • 涉及到的java原理:
class Solution {
    public String minWindow(String s, String t) {
        if (t.length() > s.length()) return "";
        int[] characters = new int[128];
        boolean[] flag = new boolean[128];
        for (int i = 0; i < t.length(); i++) {
            int index = t.charAt(i);
            flag[index] = true;
            characters[index]++;
        }
        int begin_index = 0, end_index = s.length(),count = 0;
        for (int r = 0,l = 0; r < s.length(); r++) {
            int indexR = s.charAt(r);
            if (flag[indexR] && characters[indexR]-- > 0) {
                count++;
            }
            while (count == t.length()) {
                int indexL = s.charAt(l);
                if (flag[indexL] && ++characters[indexL] > 0) {
                    if (r-l+1 <  end_index-begin_index +1) {
                        begin_index = l;
                        end_index = r;
                    }
                    count--;
                }
                l++;
            }
        }
        return end_index == s.length() ? "" : s.substring(begin_index,end_index+1);
    }
}

No.5 Sum of Square Numbers

题目链接:https://leetcode.com/problems/sum-of-square-numbers/

涉及到的算法:双指针
解题思路:
Two Sum 变种
这里需要注意两点:
  1. 不能将r=c/2,而要使用java的开根号方法double Math.sqrt(),向下取整,防止溢出
  2. 因为 0 <= c && c <= 231 - 1,我们在计算时如果使用 a2 + b2 容易溢出,可以使用 c - a2 的形式去判断,就不会溢出了
class Solution {
    public boolean judgeSquareSum(int c) {
        if (c <= 2) return true;
        int l = 0, r = (int)(Math.sqrt(c));
        while(l <= r) {
            int left = l * l;
            int right = c - left;
            if (right == r * r) {
                return true;
            } else if (right < r * r) {
                r --;
            } else {
                l ++;
            }
        }
        return false;
    }
}

No.6 Valid Palindrome II

题目链接:https://leetcode.com/problems/valid-palindrome-ii/

涉及到的算法:双指针
解题思路:左右各一个指针,遇见不同时尝试跳过左边的数字和跳过右边的数字两种情况就可以。
class Solution {
    public boolean validPalindrome(String s) {
        int l = 0, r = s.length() - 1;
        while (l < r && s.charAt(l) == s.charAt(r)) {
            l++;r--;
        }
        if (s.charAt(l) == s.charAt(r)) return true;
        return isPalindrome(s.substring(l + 1,r + 1)) || isPalindrome(s.substring(l,r));
    }
    private boolean isPalindrome(String s) {
        int l = 0, r = s.length() - 1;
        while (l < r && s.charAt(l) == s.charAt(r)) {
            l++;r--;
        }
        if (s.charAt(l) == s.charAt(r)) return true;
        return false;
    }
}

No.7 Longest Word in Dictionary through Deleting

题目链接:https://leetcode.com/problems/longest-word-in-dictionary-through-deleting/

涉及到的算法:双指针
解题思路:
先给 dictionary 排序,排完以后就是一个简单的对比string的问题
class Solution {
    public String findLongestWord(String s, List<String> dictionary) {
        Collections.sort(dictionary,(a,b) -> {
            if (a.length() != b.length()) {
                return b.length() - a.length();
            } 
            for (int i = 0; i < a.length(); i++) {
                if (a.charAt(i) != b.charAt(i)) {
                     return a.charAt(i) - b.charAt(i);
                }
            }
            return 0;
        });
        for(int i = 0; i < dictionary.size();i++) {
            if (dictionary.get(i).length() > s.length()) {
                continue;
            }
            String target = dictionary.get(i);
            int j = 0,k = 0;
            for(; j < s.length() && k < target.length(); j++) {
                if (s.charAt(j) == target.charAt(k)) {
                    k++;
                }
            }
            if (k == target.length()) {
                return target;
            }
        }
        return "";
    }
}

No. 8 Longest Substring with At Most K Distinct Characters

本题需要leetcode会员,贫穷的我选择直接看好心人的题解T T:https://aaronice.gitbook.io/lintcode/two_pointers/longest_substring_with_at_most_k_distinct_characters
涉及到的java知识:
题目:
解题思路:
求一个最长的substring的length,可以知道我们的思路是采用一个双指针的滑动窗口,在滑动的过程中去更新这个length,生息的问题是如何去维护这个滑动窗口。
我们要能确定这个这个substring的窗口中有几种字符需要额外开辟一块存储空间,去存储在这个窗口中哪些字符出现了,出现了几次。
我们需要获取在这个窗口中出现的distinct character的数量,但是数组无法确定究竟有哪些不同的character被存入,所以我们要换用可以直接获得size的hashmap进行储存,开辟一块存储,存储对应character出现次数的index
如何滑动:
设置一个左指针firstIndex 一个右指针endInex表示滑动窗口的起始与结尾,每次将endInex右++,将其指向的character存入hashMap,如果曾经有就将其次数++;
如果此时hashMap的size已经大于k了,就可以开始移动左指针firstIndex,进行删除操作,直到size不再大于k;
每次移动右指针时更新最长的值,最后返回记录的最长的值
#力扣刷题##逃离互联网#
全部评论

相关推荐

02-25 09:55
已编辑
门头沟学院 Java
2.4&nbsp;一面2.6&nbsp;二面2.9&nbsp;三面(hr面)2.13&nbsp;oc1.15号收到面试电话那会就开始准备,因为一开始没底所以选择推迟一段时间面试,之后开始准备八股,准备实习可能会问的东西,这期间hot100过了有六七遍,真的是做吐了快,八股也是背了忘,忘了背,面经也看了很多,虽然最后用上的只有几道题,可是谁知道会问什么呢自从大二上开始学java以来,一开始做外卖,点评,学微服务,大二下五六月时,开始投简历,哎,投了一千份了无音讯,开始怀疑自己(虽然能力确实很一般),后来去到一家小小厂,但是并不能学到什么东西,而且很多东西都很不规范,没待多久便离开,大二暑假基本上摆烂很怀疑自己,大三上因为某些原因开始继续学,期间也受到一俩个中小厂的offer,不过学校不知道为啥又不允许中小厂实习只允许大厂加上待遇不太好所以也没去,感觉自己后端能力很一般,于是便打算转战测开,学习了一些比较简单的测试理论(没有很深入的学),然后十二月又开始继续投,java和测开都投,不过好像并没有几个面试,有点打击不过并没有放弃心里还是想争一口气,一月初因为学校事比较多加上考试便有几天没有继续投,10号放假后便继续,想着放假应该很多人辞职可能机会大一点,直到接到字节的面试,心里挺激动的,总算有大厂面试了,虽然很开心,但同时压力也很大,心里真的很想很想很想进,一面前几天晚上都睡不好觉,基本上都是二三点睡六七点醒了,一面三十几分钟结束,问的都不太难,而且面试官人挺好但是有些问题问的很刁钻问到了测试的一些思想并不是理论,我不太了解这方面,但是也会给我讲一讲他的理解,但是面完很伤心觉得自己要挂了。但是幸运的是一面过了(感谢面试官),两天后二面,问的同样不算难,手撕也比较简单,但也有一两个没答出来,面试官人很好并没有追问,因为是周五进行的二面,没有立即出结果,等到周一才通知到过了,很煎熬的两天,根本睡不好,好在下周一终于通知二面过了(感谢面试官),然后约第二天三面,听别的字节同学说hr面基本上是谈薪资了,但是我的并不是,hr还问了业务相关的问题,不过问的比较浅,hr还问我好像比较紧张,而且hr明确说了还要比较一下,我说我有几家的面试都拒了就在等字节的面试,三面完后就开始等结果,这几天干啥都没什么劲,等的好煎熬,终于13号下午接到了电话通知oc了,正式邮件也同时发了,接到以后真的不敢信,很激动但更重要的是可以松一口气了,可以安心的休息一下了终于可以带着个好消息过年了,找实习也可以稍微告一段落了,虽然本人很菜,但是感谢字节收留,成为忠诚的节孝子了因为问的比较简单,面经就挑几个记得的写一下一面:1.实习项目的难点说一下2.实习中用到了哪些测试方法3.针对抖音评论设计一下测试用例4.手撕:合并两个有序数组二面:1.为什么转测开2.线程进程区别,什么场景适合用哪个3.发送一个朋友圈,从发出到别人看到,从数据流转的角度说一下会经历哪些过程4.针对抖音刷到广告视频设计测试用例5.手撕:无重复字符的最长字串
厂办龚彪:锲而不舍 金石可镂
查看8道真题和解析
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务