leetcode_top100_easy

1.最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

class MinStack {
    Stack<Integer> stack;
    Stack<Integer> minStack;
    /** initialize your data structure here. */
    public MinStack() {
        stack=new Stack<>();
        minStack=new Stack<>();
    }
    
    public void push(int val) {
        if(stack.isEmpty()){
            minStack.push(val);
        }else{
            if(val<minStack.peek()){  //minStack每次入栈的时候需要和栈顶做比较
                minStack.push(val);
            }else{
                minStack.push(minStack.peek());
            }
        }
        stack.push(val);
    }
    public void pop() {
        stack.pop();
        minStack.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int getMin() {
        return minStack.peek();
    }
}

https://leetcode-cn.com/problems/min-stack/solution/zui-xiao-zhan-by-leetcode-solution/

2.多数元素
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
(1)map统计
(2)投票法
思路:如果我们把众数记为 +1,把其他数记为−1,将它们全部加起来,显然和大于 0,从结果本身我们可以看出众数比其他数多。(要这么想,即使众数是第一个,那也能将其他的数都抵消掉,更不用说若第一个不是众数,那么最后留下的也是众数)

        int count=0;
        Integer res=null;
        for(int num : nums){
            if(count==0){
                res=num;
            }
            if(num==res){
                count++;
            }else{
                count--;
            }
        }
        return res;

(3)排序

	Arrays.sort(nums);
    return nums[nums.length/2];

3.回文链表
请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false
示例 2:

输入: 1->2->2->1
输出: true
(1)复制到数组中,两个指针一个放到0,一个放到size-1,一起往中间走

class Solution {
    public boolean isPalindrome(ListNode head) {
        List<Integer> vals = new ArrayList<Integer>();

        // 将链表的值复制到数组中
        ListNode currentNode = head;
        while (currentNode != null) {
            vals.add(currentNode.val);
            currentNode = currentNode.next;
        }

        // 使用双指针判断是否回文
        int front = 0;
        int back = vals.size() - 1;
        while (front < back) {
            if (!vals.get(front).equals(vals.get(back))) {
                return false;
            }
            front++;
            back--;
        }
        return true;
    }
}

(2)以下5个步骤:
找到前半部分链表的尾节点。
反转后半部分链表。
判断是否回文。
恢复链表。(本题可以不用恢复)
返回结果。

class Solution {
    public boolean isPalindrome(ListNode head) {
        if (head == null) {
            return true;
        }

        // 找到前半部分链表的尾节点并反转后半部分链表
        ListNode firstHalfEnd = endOfFirstHalf(head);
        ListNode secondHalfStart = reverseList(firstHalfEnd.next);

        // 判断是否回文
        ListNode p1 = head;
        ListNode p2 = secondHalfStart;
        boolean result = true;
        while (result && p2 != null) {
            if (p1.val != p2.val) {
                result = false;
            }
            p1 = p1.next;
            p2 = p2.next;
        }        

        // 还原链表并返回结果
        firstHalfEnd.next = reverseList(secondHalfStart);
        return result;
    }

    private ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode nextTemp = curr.next;
            curr.next = prev;
            prev = curr;
            curr = nextTemp;
        }
        return prev;
    }

    private ListNode endOfFirstHalf(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
}

4.比特位计数
给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。

示例 1:

输入: 2
输出: [0,1,1]
示例 2:

输入: 5
输出: [0,1,1,2,1,2]

(1)暴力解

    public int[] countBits(int n) {
        int [] res=new int[n+1];
        int num=0;
        int count=0;
        for(int i=0;i<=n;i++){   //遍历每个数
            num=i;
            count=0;
            while(num!=0){  //对1进行计数
                if((num&1)==1){
                    count++;
                }
                res[i]=count;
                num=num>>1;
            }
        }
        return res;
    }

(2)找规律
0~3 是两位,分别是00,01,10,11,然后 4 到 7 是三位,分别是100,101,110,111,这不就是前面多了个 1 嘛! 直接相加就可以了。。后面的以此类推即可

	public int[] countBits(int n) {
        if(n==0){
            return new int[]{0};
        }
        int [] res=new int[n+1];
        res[0]=0;
        res[1]=1;
        int mul=2;   //初始值为2
        for(int i=2;i<=n;i++){
            if(i==mul){ //该数是2的某次方,1的个数必为1
                res[i]=1;
                mul*=2;
            }else{
                res[i]=1+res[i-mul/2];  //注意mul要除2
            }
        }
        return res;
    }

5.二叉树的直径
给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

示例 :
给定二叉树

      1
     / \
    2   3
   / \     
  4   5    

返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。

思路:再计算树的高度的时候顺便计算了最大直径

class Solution {    
    int max=0;
    public int diameterOfBinaryTree(TreeNode root) {
        dfs(root);
        return max;
    }
    public int dfs(TreeNode root){
        if(root==null){
            return 0;
        }
        int left=dfs(root.left);
        int right=dfs(root.right);
        max=Math.max(max,left+right);
        return Math.max(left,right)+1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值