234-回文链表
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2->2->1
输出: true
示例 2:
输入: 1->2
输出: false
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
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;
//p2!=null 可以处理是奇数个的情况
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 endOfFirstHalf(ListNode head){
ListNode fast = head;
ListNode slow = head;
while(fast.next!=null&&fast.next.next!=null){
fast = fast.next.next;
slow = slow.next;
}
//1 2 3 2 1返回的是3 1 2 3 4 返回的是2
return slow;
}
//反转链表
private ListNode reverseList(ListNode head){
//反转链表需要双指针,一个用来标记头结点,一个用来工作
ListNode pre = new ListNode(0);
ListNode cur = head;
pre.next = null;
while(cur!=null){
cur = cur.next;
head.next = pre.next;
pre.next = head;
head = cur;
}
return pre.next;
}
}
236-二叉树的最近公共祖先
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
Map<Integer, TreeNode> parent = new HashMap<Integer, TreeNode>();
Set<Integer> visited = new HashSet<Integer>();
//深度遍历
//在添加孩子节点时记录其父亲节点
public void dfs(TreeNode root) {
if (root.left != null) {
//存放左孩子节点和root
parent.put(root.left.val, root);
dfs(root.left);
}
if (root.right != null) {
//右孩子节点和root
parent.put(root.right.val, root);
dfs(root.right);
}
}
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
dfs(root);
while (p != null) {
//添加p节点以及其祖先结点
visited.add(p.val);
p = parent.get(p.val);
}
//遍历q的祖先节点,第一个在visited中出现的就是第一个公共祖先结点
while (q != null) {
if (visited.contains(q.val)) {
return q;
}
q = parent.get(q.val);
}
return null;
}
}
238. 除自身以外数组的乘积
给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
示例:
输入: [1,2,3,4]
输出: [24,12,8,6]
class Solution {
/**
B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]-->B[i+1]=A[0]A[1]…*A[i]A[i+2]…*A[n-1]
则:left[i+1]:A[0]A[1]…*A[i] right[i+1]: A[i+2]…*A[n-1]
则:left[i] = left[i-1]*A[i-1] right[i] = right[i+1]*A[i+1]
*/
public int[] productExceptSelf(int[] nums) {
int[] B = new int[nums.length];
B[0] = 1;
//先求出左下角
for(int i=1;i<nums.length;i++){
B[i] = B[i-1]*nums[i-1];
}
int temp=1;
for(int j=nums.length-1;j>=0;j--){
B[j] = temp*B[j];
//从右到左依次累积A[j],temp即是右下角
temp = temp*nums[j];
}
return B;
}
}
239-滑动窗口最大值
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7输入:nums = [1], k = 1 输出:[1] 示例 3:
输入:nums = [1,-1], k = 1 输出:[1,-1]
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int[] res = new int[nums.length-k+1];
if(nums==null||nums.length==0||k<=0) return res;
//双端队列 保存当前窗口最大值的数组位置
//保证队列中数组的数值从大到小
Deque<Integer> queue = new LinkedList();
for(int i=0;i<nums.length;i++){
//依次把当前值和队列中最后一个值比较(队列存放的是数组中的下标)
//比最后一个值大,则删除最后一个值,然后把当前值的下标放在队列最后
//这个for循环的功能是找到当前窗口的最大值,并保存其他次大值
//如 6 2 3 deque: 0 2 ;;; 如 6 3 2 deque : 0 1 2
//依次与队尾比较,大于队尾则出队,找到更大的值,然后入队
while(!queue.isEmpty()&&nums[i]>=nums[queue.peekLast()]){
queue.pollLast();
}
//找到次大值。添加下标
queue.addLast(i);
//判断当前队列中队首的值是否有效(i-k即为窗口最左边的边界)
if(queue.peekFirst()<=i-k){
//无效则删除
queue.pollFirst();
}
//当前窗口长度为k时,保存当前窗口最大值
if(i+1>=k){
res[i+1-k] = nums[queue.peekFirst()];
}
}
return res;
}
}
240. 搜索二维矩阵 II
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int row = 0;
int cols = matrix[0].length-1;
while(row<matrix.length&&cols>=0){
if(matrix[row][cols]>target){
cols--;
}else if(matrix[row][cols]<target){
row++;
}else{
return true;
}
}
return false;
}
}