加载中...

[leetcode]第 11 天 双指针(简单)、第 12 天 双指针(简单)、第 13 天 双指针(简单)

18. 删除链表的节点

思路

class Solution {
    public ListNode deleteNode(ListNode head, int val) {
        if(head == null) return null;
        if(head.val == val) return head.next;
        ListNode cur = head;
        while(cur.next != null && cur.next.val != val)
            cur = cur.next;
        if(cur.next != null) cur.next = cur.next.next;
        return head;
    }
}

22. 链表中倒数第k个节点

思路

看了大佬的解法,太妙了
指针former先向前走n - k步,然后former和latter一起向前走,等到former = null时返回latter指向的节点。

class Solution {
    public ListNode getKthFromEnd(ListNode head, int k) {
     ListNode former = head, latter = head;
        for(int i = 0; i < k; i++)
            former = former.next;
        while(former != null) {
            former = former.next;
            latter = latter.next;
        }
        return latter;
    }
}

21. 调整数组顺序使奇数位于偶数前面

思路

可以引入伪头节点,将所有节点添加到伪头节点之后

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dum = new ListNode(0), cur = dum;
        while(l1 != null && l2 != null) {
            if(l1.val < l2.val) {
                cur.next = l1;
                l1 = l1.next;
            }
            else {
                cur.next = l2;
                l2 = l2.next;
            }
            cur = cur.next;
        }
        cur.next = l1 != null ? l1 : l2;
        return dum.next;
    }
}

52. 两个链表的第一个公共节点

思路

当两个链表都不为空时才有可能相交,因此如果二者如果有一个为null,那么一定不相交。
使用两个指针 node1,node2 分别指向两个链表 headA,headB 的头结点,然后同时分别逐结点遍历,当 node1 到达链表 headA 的末尾时,重新定位到链表 headB 的头结点;当 node2 到达链表 headB 的末尾时,重新定位到链表 headA 的头结点。

class Solution {
    ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA == null || headB == null) return null;
        ListNode A = headA, B = headB;
        while (A != B) {
            A = A != null ? A.next : headB;
            B = B != null ? B.next : headA;
        }
        return A;
    }
}

25.调整数组顺序使奇数位于偶数前面

思路

双指针,一个从头遍历一个从尾遍历。

class Solution {
    public int[] exchange(int[] nums) {
        int i = 0, j = nums.length - 1;
        while(i < j && j > 0){
            int tmp1 = nums[i], tmp2 = nums[j];
            if(nums[i] % 2 == 0) tmp1 = nums[i];
            else i++;
            if(nums[j] % 2 != 0) tmp2 = nums[j];
            else j--;
            if(tmp1 % 2 == 0 && tmp2 % 2 != 0){
                nums[i] = tmp2;
                nums[j] = tmp1;
            }
        }
        return nums;
    }
}

57. 和为s的两个数字

思路

双指针,思路和上题一样

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int i = 0, j = nums.length - 1;
        while(i < j){
            int res = nums[i] + nums[j];
            if(res < target) i++;
            else if(res > target) j--;
            else return new int[] { nums[i], nums[j] };
        }
        return new int[0];
    }
}

58 - I. 翻转单词顺序

思路

这种倒转的题第一反应是栈

class Solution {
    public String reverseWords(String s) {
        if(s == null) return s;
        Stack<String> res = new Stack<>();
        int left = 0, right = 0;
        while(right < s.length()){
            if(s.charAt(left) == ' '){
                left++;
                right = left;
                continue;
            }

            if(s.charAt(right) != ' '){
                right++;
                if(right != s.length()) continue;
            }
            res.push(s.substring(left, right));
            res.push(" ");
            left = right;
        }
        if(res.isEmpty()) return "";
        res.pop();

        StringBuilder sb = new StringBuilder();
        while(!res.isEmpty()){
            sb.append(res.pop());
        }
        return sb.toString();
    }
}

但是看官方的解法可以用API!可恶啊,还是对字符串的API不太熟练。。。

class Solution {
    public String reverseWords(String s) {
        s = s.trim();
        List<String> wordList = Arrays.asList(s.split("\\s+"));
        Collections.reverse(wordList);
        return String.join(" ", wordList);
    }
}
posted @ 2023-01-03 00:38  Vincy9501  阅读(14)  评论(0编辑  收藏  举报