力扣热题100

本文介绍了几个编程面试中常见的IT技术问题,涉及数组/链表操作(如哈希表查找、链表合并、相交链表、回文链表检测)、数组移动零、二叉树对称性、直径计算以及括号验证,展示了基本数据结构和算法在实际问题中的应用。
摘要由CSDN通过智能技术生成

1. 两数之和

时间空间复杂度为O(N),思路是:创建一个哈希表,对于每一个 x,先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
        for(int i = 0; i < nums.length; i++){
            if(hashtable.containsKey(target - nums[i])){ //存在target - x
                return new int[]{i, hashtable.get(target - nums[i])};
            }
            hashtable.put(nums[i], i);
        }
        return new int[0];
    }
}

21. 合并两个有序链表

用递归的思路:判断 l1l2 哪一个链表的头节点的值更小,递归地决定下一个添加到结果里的节点。

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        } else if (l2 == null) {
            return l1;
        } else if (l1.val < l2.val) {
            l1.next = mergeTwoLists(l1.next, l2); //选了此时的l1,再l1.next与l2比小
            return l1;
        } else {
            l2.next = mergeTwoLists(l1, l2.next);
            return l2;
        }
    }
}

160. 相交链表

思路一:哈希集合存放不重复的元素,先将A链表的结点add后,再依次判断B链表的结点是否有相同的。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        Set<ListNode> set = new HashSet<ListNode>();
        ListNode p = headA, q = headB;
        while(p != null){
            set.add(p);
            p = p.next;
        }
        while(q != null){
            if(set.contains(q)){
                return q;
            }
            q = q.next;
        }
        return null;   
    }
}

思路二:用双指针,先判断A、B链表是否为空,有空的则根本无法相交。都不为空则要同时更新pqp不为空就next,为空则指向headBq同理,最后指向同一个结点或者null,返回即可。

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

234. 回文链表

要学的思路是把链表的值复制到数组中,再用双指针进行判断。

class Solution {
    public boolean isPalindrome(ListNode head) {
        List<Integer> array = new ArrayList<Integer>();
        ListNode p = head;
        while(p != null){
            array.add(p.val);
            p = p.next;
        }
        //用双指针判断是否是回文
        int front = 0;
        int back = array.size() - 1;
        while(front < back){
            if(!array.get(front).equals(array.get(back))){
                return false;
            }
            front++;
            back--;
        }
        return true;
    }
}

283. 移动零

思路:分两次遍历,j用来记录当前数组中非0的元素,每遇到一个非0元素就往数组左边挪,遍历完后,j指向的是最后一个非0元素下标。第二次遍历就从j开始到结束,将其置为0。

class Solution {
	public void moveZeroes(int[] nums) {
		if(nums == null){
            return;
        }
        int j = 0;
        for(int i = 0; i < nums.length; i++){
            if(nums[i] != 0){
                nums[j++] = nums[i];
            }
        }
        for(int i = j; i < nums.length; i++){
            nums[i] = 0;
        }
	}
}	

101. 对称二叉树

要镜像对称,左右两边是相当的。递归的终止条件:两个结点为空;其中一个结点为空;两个结点不相等。随后再比较left.left, right.rightleft.right, right.left

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root == null){
            return true;
        }
        return dfs(root.left, root.right);
    }

    public boolean dfs(TreeNode left, TreeNode right){
        if(left == null && right == null){
            return true;
        }else if(left == null || right == null){
            return false;
        }else if(left.val != right.val){
            return false;
        }
        return dfs(left.left, right.right) && dfs(left.right, right.left);
    }
}

543. 二叉树的直径

思路:求直径等同于求路径经过节点数的最大值 - 1。定义一个递归函数,返回该节点为根的子树的深度。先递归调用左儿子和右儿子求得它们为根的子树的深度 L 和 R,则该节点为根的子树的深度即为max(L, R) + 1。设置一个全局变量ans记录,最后返回ans - 1就是直径。

class Solution {
    int ans;
    public int diameterOfBinaryTree(TreeNode root) {
        ans = 1;
        depth(root);
        return ans - 1;
    }
    public int depth(TreeNode node){
        if(node == null){
            return 0;
        }
        int L = depth(node.left);
        int R = depth(node.right);

        //ans是所有节点经过节点数的最大值
        ans = Math.max(ans, L + R + 1);
        //返回该节点为根的子树的深度
        return Math.max(L, R) + 1;
    }
}

20. 有效的括号

class Solution {
    public boolean isValid(String s) {
       if(s.isEmpty()){
           return true;
       } 
       Stack<Character> stack = new Stack<Character>();
       for(char c : s.toCharArray()){
           if(c == '('){
               stack.push(')');
           }else if(c == '{'){
               stack.push('}');
           }else if(c=='['){
               stack.push(']');
           }else if(stack.empty() || c != stack.pop()){
               return false;
           }
       }
       if(stack.empty()){
            return true;
        }
        return false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值