leetcode-day11

155.设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

class MinStack {
    Deque<Integer> xStack;
    Deque<Integer> minStack;

    public MinStack() {
        //初始化数据栈和最小栈
        xStack = new LinkedList<Integer>();
        minStack = new LinkedList<Integer>();
        minStack.push(Integer.MAX_VALUE);
    }
    
    public void push(int x) {
        xStack.push(x);
        //比较大小决定压入哪个入最小栈,LinkedList元素可以重复
        minStack.push(Math.min(minStack.peek(), x));
    }
    
    public void pop() {
        xStack.pop();
        minStack.pop();
    }
    
    public int top() {
        return xStack.peek();
    }
    
    public int getMin() {
        return minStack.peek();
    }
}

160.给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
双指针:

 //若相交,链表A:a+c,链表B:b+c,a+c+b+c=b+c+a+c->a+c+b=b+c+a,则会在公共处c起点相遇。
 //若不相交,a+b=b+a。因此相遇处是NULL。
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) {//若某个单链表为空
            return null;
        }
        ListNode pA = headA, pB = headB;
        while (pA != pB) {
            pA = pA == null ? headB : pA.next;
            pB = pB == null ? headA : pB.next;
        }
        return pA;
    }
}

哈希集合:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        Set<ListNode> seen = new HashSet<ListNode>();
        ListNode temp = headA;
        //把headA中节点全部加进seen中
        while (temp != null) {
            seen.add(temp);
            temp = temp.next;
        }
        temp = headB;
        //headB一直前进直到某一节点被seen包含,返回该节点
        while (temp != null) {
            if (seen.contains(temp)) {
                return temp;
            }
            temp = temp.next;
        }
        return null;
    }
}

169.给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
Boyer-Moore 投票算法(🐂):

class Solution {
    public int majorityElement(int[] nums) {
        //摩尔投票法,遇到相同的数,就投一票,遇到不同的数,就减一票,最后还存在票的数就是众数
        int count = 0, result = -1;
        for(int num : nums)
        {
            if(count == 0) result = num;
            if(num == result) count++;
            else count--;
        }
        return result;
    }
}

排序法:

class Solution {
    //由于众数出现的频率大于n/2,所以在排序之后众数必存在于下标[n/2]处(本题默认数组中是一定存在众数的,所以返回下标[n/2]可行)
    public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length / 2];
    }
}

198.你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。在这里插入图片描述
动态规划+滚动数组:

class Solution {
    public int rob(int[] nums) {
        int length = nums.length;
        if (nums == null || length == 0) {//没有房屋
            return 0;
        }
        if (length == 1) {//只有一间房屋,则偷窃该房屋
            return nums[0];
        }
        int first = nums[0], second = Math.max(nums[0], nums[1]);//只有两间房屋,选择其中金额较高的房屋进行偷窃
        for (int i = 2; i < length; i++) {
            int temp = second;
            second = Math.max(first + nums[i], second);//这间偷与不偷选最大
            first = temp;
        }
        return second;
    }
}

200.给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
岛屿类问题的通用解法、DFS 遍历框架⭐@nettee
深度优先搜索:

class Solution {
    public int numIslands(char[][] grid) {
        int res = 0;
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j] == '1') {
                    dfsGrid(grid, i, j);
                    res++;
                }
            }
        }
        return res;
    }
    private void dfsGrid(char[][] grid, int row, int col) {
        //判断 base case(判断坐标 (r, c) 是否在网格中,如果坐标 (r, c) 超出了网格范围,直接返回)
        if (row >= grid.length || col >= grid[0].length || row < 0 || col < 0) {
            return;
        }
        //如果这个格子已遍历过或者不是岛屿,直接返回
        if (grid[row][col] != '1') {
            return;
        }
        grid[row][col] = '2';//将格子标记为「已遍历过」
        //访问上、下、左、右四个相邻结点
        dfsGrid(grid, row - 1, col);
        dfsGrid(grid, row + 1, col);
        dfsGrid(grid, row, col - 1);
        dfsGrid(grid, row, col + 1);
    }
}

广度优先搜索:

class Solution {
    public int numIslands(char[][] grid) {
        int res = 0;
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j] == '1') {
                    bfs(grid, i, j);
                    res++;
                }
            }
        }
        return res;
    }
    private void bfs(char[][] grid, int i, int j){
        Queue<int[]> list = new LinkedList<>();
        list.add(new int[] { i, j });
        while(!list.isEmpty()){
            int[] cur = list.remove();
            i = cur[0]; 
            j = cur[1];
            //判断队列首部节点 (i, j) 是否未越界且为 1
            if(0 <= i && i < grid.length && 0 <= j && j < grid[0].length && grid[i][j] == '1') {
                grid[i][j] = '2';//将格子标记为「已遍历过」
                //将此节点上下左右节点 (i+1,j),(i-1,j),(i,j+1),(i,j-1) 加入队列
                list.add(new int[] { i + 1, j });
                list.add(new int[] { i - 1, j });
                list.add(new int[] { i, j + 1 });
                list.add(new int[] { i, j - 1 });
            }
        }
    }
}

并查集※
206.给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
反转链表动画图示⭐@王尼玛
双指针迭代:

class Solution {
	public ListNode reverseList(ListNode head) {
		//申请节点,pre和 cur,pre指向null
		ListNode pre = null;
		ListNode cur = head;
		ListNode tmp = null;
		while(cur!=null) {
			//记录当前节点的下一个节点
			tmp = cur.next;
			//然后将当前节点指向pre
			cur.next = pre;
			//pre和cur节点都前进一位
			pre = cur;
			cur = tmp;
		}
		return pre;
	}
}

递归:(不懂欸※)

class Solution {
	public ListNode reverseList(ListNode head) {
		//递归终止条件是当前为空或者下一个节点为空
		if(head==null || head.next==null) {
			return head;
		}
		//这里的cur就是最后一个节点
		ListNode cur = reverseList(head.next);
		head.next.next = head;
		//防止链表循环,需要将head.next设置为空
		head.next = null;
		//每层递归函数都返回cur,也就是最后一个节点
		return cur;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值