leetcode一周题解(20220411-20220417)

这周挑战了一下周赛,结果卡在第三题了,果然还是太菜了.....,最后一题二叉树等刷到二叉树专题再加进来!

这周主要把链表的基本题目全刷完了。

#6072 转角路径的乘积中最多能有几个尾随零

周赛时想到了其实就是找5和2的个数和前缀和,但是最后转角时处理不好,最后也没写出来,参考了大佬的方法写了一个Java版的。

主要是要前缀和找5和2的个数,然后遍历时,要考虑四边情况(从左出发到上,从左出发到下,从右出发到上,从右出发到下)取最大值。

class Solution {
    public int getCntFactor(int x,int factor){
        int ret=0;
        while(x%factor==0){
            ret++;
            x/=factor;
        }
        return ret;
    }
    public int maxTrailingZeros(int[][] grid) {
        int n=grid.length,m=grid[0].length;
        int[][]row2=new int[n+1][m+1];
        int[][]col2=new int[n+1][m+1];
        int[][]row5=new int[n+1][m+1];
        int[][]col5=new int[n+1][m+1];
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                int cnt2=getCntFactor(grid[i-1][j-1],2);
                int cnt5=getCntFactor(grid[i-1][j-1],5);
                row2[i][j]=row2[i][j-1]+cnt2;
                col2[i][j]=col2[i-1][j]+cnt2;
                row5[i][j]=row5[i][j-1]+cnt5;
                col5[i][j]=col5[i-1][j]+cnt5;

            }
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                //从左边出发,到上边结束
                ans=Math.max(ans,Math.min(row2[i][j]+col2[i-1][j],row5[i][j]+col5[i-1][j]));
                //从左边出发,到下边结束
                ans=Math.max(ans,Math.min(row2[i][j]+col2[n][j]-col2[i][j],row5[i][j]+col5[n][j]-col5[i][j]));
                //从右边出发,到上边结束
                ans=Math.max(ans,Math.min(row2[i][m] - row2[i][j] + col2[i][j], row5[i][m] - row5[i][j] + col5[i][j]));
                //从右边出发,到下边结束
                ans= Math.max(ans, Math.min(row2[i][m] - row2[i][j] + col2[n][j] - col2[i-1][j],  row5[i][m] - row5[i][j] + col5[n][j] - col5[i-1][j]));
            }
        }
        return ans;

    }
}
#567 字符串的排列

利用ASCII码,用滑动窗口来判断两个字符串关系。

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        if(s1.length()>s2.length()) return false;
        int left=0,right=s1.length();
        int[]a1=new int[26];
        int[]a2=new int[26];
        for(int i=0;i<s1.length();i++){
            a1[s1.charAt(i)-'a']++;
            a2[s2.charAt(i)-'a']++;
        }
        if(Arrays.equals(a1,a2)) return true;
        while(right<s2.length()){
            a2[s2.charAt(right)-'a']++;
            a2[s2.charAt(left)-'a']--;
            if(Arrays.equals(a1,a2)) return true;
            left++;
            right++;
        }
        return false;

    }
}

#713 乘积小于K的子数组

双指针,要注意是从右到左统计,避免重复(滑动就完事了)

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        int left=0,answer=0,product=1;
        for(int right=0;right<nums.length;right++){
            product*=nums[right];
            while(product>=k&&left<=right){
                product/=nums[left++];
            }
            answer+=right-left+1;
        }
        return answer;

    }
}
#283 移动零

直接忽视零,最后再补上

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

    }
}

#977 有序数组的平方

双指针解决

class Solution {
    public int[] sortedSquares(int[] nums) {
        int l=0;
        int r=nums.length-1;
        int[]res=new int[nums.length];
        int j=nums.length-1;
        while(l<=r){
            if(nums[l]*nums[l]>nums[r]*nums[r]){
                res[j--]=nums[l]*nums[l++];
            }else{
                res[j--]=nums[r]*nums[r--];
            }
        }
        return res;

    }
}
#3 无重复字符的最长子串

滑动窗口解决,用哈希表统计出现的字符

class Solution {
    public int lengthOfLongestSubstring(String s) {
        // 哈希集合,记录每个字符是否出现过
        Set<Character> occ = new HashSet<Character>();
        int n = s.length();
        // 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
        int rk = -1, ans = 0;
        for (int i = 0; i < n; ++i) {
            if (i != 0) {
                // 左指针向右移动一格,移除一个字符
                occ.remove(s.charAt(i - 1));
            }
            while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
                // 不断地移动右指针
                occ.add(s.charAt(rk + 1));
                ++rk;
            }
            // 第 i 到 rk 个字符是一个极长的无重复字符子串
            ans = Math.max(ans, rk - i + 1);
        }
        return ans;
    }
}
#611 有效三角形的个数

妙用最长边简化

class Solution {
    public int triangleNumber(int[] nums) {
        int ans=0;
        if(nums==null||nums.length==0){
            return ans;
        }
        Arrays.sort(nums);
        for(int i=nums.length-1;i>1;i--){
            int start=0;
            int end=i-1;
            while(start<end){
                if(nums[start]+nums[end]>nums[i]){
                    ans+=(end-start);//start、start+1.....end-1;
                    end--;
                }else{
                    start++;
                }
            }
        }
        return ans;
  

    }
}
#844 比较含退格的字符串

1.栈的运用

class Solution {
    public boolean backspaceCompare(String s, String t) {
        StringBuilder stack_s=new StringBuilder();
        StringBuilder stack_t=new StringBuilder();
        for(char c:s.toCharArray()){
            if(c!='#'){
                stack_s.append(c);
            }else if(stack_s.length()>0){
                stack_s.deleteCharAt(stack_s.length()-1);
            }
        }
        for(char c:t.toCharArray()){
            if(c!='#'){
                stack_t.append(c);
            }else if(stack_t.length()>0){
                stack_t.deleteCharAt(stack_t.length()-1);
            }
        }
        return stack_s.toString().equals(stack_t.toString());

    }
}

2.双指针模拟

class Solution {
    public boolean backspaceCompare(String s, String t) {
        int i=s.length()-1,j=t.length()-1;
        int skips=0,skipt=0;
        char[]S=s.toCharArray();
        char[]T=t.toCharArray();
        while(true){
            while(i>=0){
                if(S[i]=='#') skips++;
                else{
                    if(skips>0) skips--;
                    else break;
                }
                i--;
            }
            while(j>=0){
                if(T[j]=='#') skipt++;
                else{
                    if(skipt>0) skipt--;
                    else break;
                }
                j--;
            }
            if(i<0||j<0) break;
            if(S[i]!=T[j]) return false;
            i--;
            j--; 
        }
        if(i==-1&&j==-1) return true;
        return false;

    }
}

#34 在排序数组中查找元素的第一个和最后一个元素的位置

二分查找

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[]res={-1,-1};
        int index=binarySearch(nums,target);
        if(index==-1){
            return res;
        }
        int left=index,right=index;
        while(left-1>=0&&nums[left-1]==nums[index]){
            left--;
        }
        while(right+1<nums.length&&nums[right+1]==nums[index]){
            right++;
        }
        return new int[]{left,right};
    }
    public int binarySearch(int[]nums,int target){
        int left=0;
        int right=nums.length-1;
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]==target){
                return mid;
            }else if(nums[mid]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return -1;
    }
}

#5 最长回文子串

好题!

class Solution {
    public String longestPalindrome(String s) {
        if(s==null||s.length()==0){
            return"";
        
        }
        int[]range=new int[2];
        char[]str=s.toCharArray();
        for(int i=0;i<s.length();i++){
            i=findLongest(str,i,range);
        }
        return s.substring(range[0],range[1]+1);
    }
    public static int findLongest(char[]str,int low,int[]range){
        int high=low;
        while(high<str.length-1&&str[high+1]==str[low]){
            high++;
        }
        int ans=high;
        while(low>0&&high<str.length-1&&str[low-1]==str[high+1]){
            low--;
            high++;
        }
        if(high-low>range[1]-range[0]){
            range[0]=low;
            range[1]=high;
        }
        return ans;
    }
}

#206 反转链表

链表的反转是很常用的操作,可以通过画图理解一下next,pre的次序(其实很好理解,pre就是当前节点的前一个,next就是当前节点的后一个,时刻保证这两个是保持这样的变化就可以)

/*
public class ListNode {//define listNode
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode ReverseList(ListNode head) {
        ListNode pre=null;//pre ListNode
        ListNode next=null;//next ListNode
        while(head!=null){
            next=head.next;
            head.next=pre;//reverse ListNode
            pre=head;
            head=next;
        }
        return pre;

    }
}

链表内指定区间反转_牛客题霸_牛客网

指定区间反转和整体反转略有不同。这个需要理解一下,

辅助理解
​​​

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param m int整型 
     * @param n int整型 
     * @return ListNode类
     */
    public ListNode reverseBetween (ListNode head, int m, int n) {
        ListNode res=new ListNode(-1);
        res.next=head;
        ListNode cur=head;
        ListNode pre=res;
        for(int i=1;i<m;i++){//the pre m nodes remain the same
            pre=cur;
            cur=cur.next;
        }
        for(int i=m;i<n;i++){
            ListNode nextNode=cur.next;
            cur.next=nextNode.next;
            nextNode.next=pre.next;
            pre.next=nextNode;
        }
        return res.next;
        
    }
}

#25 K 个一组翻转链表

 递归解决每k个一组

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode reverseKGroup (ListNode head, int k) {
        ListNode tail=head;
        for(int i=0;i<k;i++){//find k tail Node
            if(tail==null){
                return head;
            }
            tail=tail.next;
        }
        ListNode pre=null;
        ListNode cur=head;
        while(cur!=tail){
            ListNode temp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=temp;
        }
        head.next=reverseKGroup(tail,k);//recursion
        return pre;
    }
}

java 快排模板:

public class QuickSort {
	private void swap(int[] arr, int i, int j) {
		int temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}
	
	public void quickSort(int[] arr, int start, int end) {
		if (start >= end)
			return;
		int k = arr[start];
		int i = start, j = end;
		while (i != j) {
			while (i < j && arr[j] >= k)
				--j;
			swap(arr, i, j);
			while (i < j && arr[i] <= k)
				++i;
			swap(arr, i, j);
		}
		quickSort(arr, start, i - 1);
		quickSort(arr, i + 1, end);
	}
	
	public static void main(String[] args) {
		int[] arr = {5, 2, 6, 9, 1, 3, 4, 8, 7, 10};
		new QuickSort().quickSort(arr, 0, arr.length - 1);
		System.out.println(Arrays.toString(arr));
	}
}

java归并排序模板:

public class MergeSort {
	public static void merge_sort(int q[], int left, int right)
	{
	    if (left >= right) return;
	    int []tmp=new int[q.length];

	    int mid = left + right >> 1;
	    merge_sort(q, left, mid);
	    merge_sort(q, mid + 1, right);

	    int k = 0, i = left, j = mid + 1;
	    while (i <= mid && j <= right)
	        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
	        else tmp[k ++ ] = q[j ++ ];

	    while (i <= mid) tmp[k ++ ] = q[i ++ ];
	    while (j <= right) tmp[k ++ ] = q[j ++ ];

	    for (i = left, j = 0; i <= right; i ++, j ++ ) q[i] = tmp[j];
	}
	public static void main(String[]args) {
		int[]arr= {5,4,2,1,3};
		System.out.println("The original list is:");
		for(int i=0;i<arr.length;i++) System.out.print(arr[i]+" ");
		System.out.println(" ");
		merge_sort(arr,0,arr.length-1);
		System.out.println("The mergesorted list is:");
		for(int i=0;i<arr.length;i++) System.out.print(arr[i]+" ");
	}

}

#23 合并K个升序链表

分治合并,两个两个合并,递归合成k个

代码如下:

/**
 * 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 ListNode merge(ListNode list1,ListNode list2){//TwoMerge
        if(list1==null) return list2;
        if(list2==null) return list1;
        ListNode head=new ListNode(0);
        ListNode cur=head;
        while(list1!=null&list2!=null){
            if(list1.val>list2.val){
                cur.next=list2;
                list2=list2.next;
            }else{
                cur.next=list1;
                list1=list1.next;
            }
            cur=cur.next;
        }
        if(list1!=null){
            cur.next=list1;
        }
        if(list2!=null){
            cur.next=list2;
        }
        return head.next;
    }
    ListNode divideMerge(ListNode[]lists,int left,int right){//divide space
        if(left>right){
            return null;
        }else if(left==right){
            return lists[left];
        }
        int mid=left+right>>1;
        return merge(divideMerge(lists,left,mid),divideMerge(lists,mid+1,right));
    }
    public ListNode mergeKLists(ListNode[] lists) {
        return divideMerge(lists,0,lists.length-1);

    }
}
#141 环形链表

快慢指针,easy;如果有循环的话,那快慢指针必定相逢!

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null){
            return false;
        }
        ListNode fast=head;
        ListNode slow =head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            if(fast==slow){
                return true;
            }
        }
        return false;
        
    }
}

2.抖机灵做法;

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        int count=10000;//leetcode 测试用例最多10000个
        
        while(head!=null&&count>0){
            head=head.next;
            count--;
        }
        if(head==null)
            return false;
            
        return true;
        
        
    }
}
#剑指 Offer II 022 链表中环的入口节点

1.HashMap<ListNode,Boolean>map 容易理解并且解决,但是效率好像不是很高

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode node=head;
        HashMap<ListNode,Boolean>map=new HashMap<>();
        while(node!=null){
            if(map.containsKey(node)){
                return node;
            }else{
                map.put(node,true);
                node=node.next;
            }
        }
        return null;
        
    }
}

2.数学找规律求解,快慢指针有点难理解,但是效率好像快一点

n为任意数

fast的路程是:a+b+n(b+c),fast=2*slow;slow=a+b;

则可得a+n(b+c)+b=2(a+b)⟹a=c+(n−1)(b+c)

所以再用一个指针从头走,slow也走,再次相遇就是入口处。

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode hasCycle(ListNode head){
        if(head==null) return null;
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            if(fast==slow){
                return slow;
            }
        }
        return null;

    }
    public ListNode detectCycle(ListNode head) {
        ListNode slow=hasCycle(head);
        ListNode fast=head;
        if(slow==null) return null;
        while(fast!=slow){
            fast=fast.next;
            slow=slow.next;
        }
        return slow;

        
    }
}

#剑指 Offer II 025 链表中的两数相加

1.用栈的性质解决

两个栈压入,再弹出相加,记下进位

/**
 * 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 ListNode addTwoNumbers(ListNode head1, ListNode head2) {
        Stack<ListNode>stack1=new Stack<>();
        Stack<ListNode>stack2=new Stack<>();
        ListNode p1=head1;
        ListNode p2=head2;
        while(p1!=null){
            stack1.push(p1);
            p1=p1.next;
        }
        while(p2!=null){
            stack2.push(p2);
            p2=p2.next;
        }
        int carry=0;
        ListNode ans=new ListNode(0);
        ListNode cur=ans;
        while(!stack1.isEmpty()||!stack2.isEmpty()){
            int pp1=!stack1.isEmpty()?stack1.pop().val:0;
            int pp2=!stack2.isEmpty()?stack2.pop().val:0;
            int plus=carry+pp1+pp2;
            carry=plus/10;
            ListNode newNode=new ListNode(plus%10);
            newNode.next=cur.next;
            cur.next=newNode;
        }
        if(carry>0){
            ans.val=1;
            return ans;
        }else{
            return ans.next;
        }

    }
}

2.两次链表翻转

/**
 * 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 ListNode reverseListNode(ListNode head){
        if(head==null){
            return head;
        }
        ListNode pre=null;
        ListNode cur=head;
        while(cur!=null){
            ListNode temp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;
    }
    public ListNode addTwoNumbers(ListNode head1, ListNode head2) {
        if(head1==null){
            return head2;
        }
        if(head2==null){
            return head1;
        }
        head1=reverseListNode(head1);
        head2=reverseListNode(head2);
        int carry=0;
        ListNode ans=new ListNode(-1);
        ListNode head=ans;
        while(head1!=null||head2!=null||carry!=0){
            int val1=head1==null?0:head1.val;
            int val2=head2==null?0:head2.val;
            int temp=val1+val2+carry;
            carry=temp/10;
            temp=temp%10;
            head.next=new ListNode(temp);
            head=head.next;
            if(head1!=null){
                head1=head1.next;
            }
            if(head2!=null){
                head2=head2.next;
            }
        }
        return reverseListNode(ans.next);

    }
}
#剑指 Offer II 077 链表排序

1.链表的冒泡排序(牛客能过,但leetcode超时,的确效率低,但容易想容易写)

/**
 * 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 ListNode sortList(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
        ListNode move=head;
        while(move.next!=null){
            ListNode temp=move.next;
            while(temp!=null){
                if(temp.val<move.val){
                    int val=move.val;
                    move.val=temp.val;
                    temp.val=val;
                }
                temp=temp.next;
            }
            move=move.next;
        }
        return head;

    }
}

2.链表的归并排序(效率高)

/**
 * 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 ListNode sortList(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
        return mergesort(head);

    }
    public ListNode mergesort(ListNode head){
        if(head.next==null){
            return head;
        }
        ListNode fast=head,slow=head,pre=null;
        while(fast!=null&&fast.next!=null){
            pre=slow;
            fast=fast.next.next;
            slow=slow.next;
        }
        pre.next=null;
        ListNode left=mergesort(head);
        ListNode right=mergesort(slow);
        return merge(left,right);
    }
    public ListNode merge(ListNode left,ListNode right){
        ListNode dummy=new ListNode(-1);
        ListNode cur=dummy;
        while(left!=null&&right!=null){
            if(left.val<right.val){
                cur.next=left;
                left=left.next;
            }else{
                cur.next=right;
                right=right.next;
            }
            cur=cur.next;
        }
        if(left!=null){
            cur.next=left;
        }
        if(right!=null){
            cur.next=right;
        }
        return dummy.next;
    }
}
#234 回文链表

快慢指针,一半翻转比较是否回文

/**
 * 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) {
        ListNode slow=head,fast=head;
        while(fast!=null&&fast.next!=null){
            slow=slow.next;
            fast=fast.next.next;
        }
        ListNode reverseList=reverse(slow);
        ListNode head1=reverseList;
        ListNode head2=head;
        while(head1!=null){
            if(head1.val!=head2.val){
                return false;
            }else{
                head1=head1.next;
                head2=head2.next;
            }
        }
        return true;
    }
    public ListNode reverse(ListNode head){
        ListNode pre=null;
        ListNode cur=head;
        while(cur!=null){
            ListNode next=cur.next;
            cur.next=pre;
            pre=cur;
            cur=next;
        }
        return pre;
    }
}
#328 奇偶链表

奇偶指针,遍历

/**
 * 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 ListNode oddEvenList(ListNode head) {
        if(head==null){
            return null;
        }
        ListNode odd=head;
        ListNode even=head.next;
        ListNode evenHead=even;
        while(even!=null&&even.next!=null){
            odd.next=even.next;
            odd=odd.next;
            even.next=odd.next;
            even=even.next;
        }
        odd.next=evenHead;
        return head;

    }
}
#83 删除排序链表中的重复元素

简单模拟

/**
 * 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 ListNode deleteDuplicates(ListNode head) {
        if(head==null) return null;
        ListNode cur=head;
        while(cur!=null&&cur.next!=null){
            if(cur.val==cur.next.val){
                cur.next=cur.next.next;
            }else{
                cur=cur.next;
            }

        }
        return head;

    }
}

递归好像简洁明了一点

/**
 * 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 ListNode deleteDuplicates(ListNode head) {
        if(head==null||head.next==null){
            return head;
        }
        head.next=deleteDuplicates(head.next);
        if(head.val==head.next.val) head=head.next;
        return head;

    }
}

#82 删除排序链表中的重复元素 II

头指针,递归解决

/**
 * 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 ListNode deleteDuplicates(ListNode head) {
        if(head==null){
            return null;
        }
        ListNode ans=new ListNode(0);
        ans.next=head;
        ListNode cur=ans;
        while(cur.next!=null&&cur.next.next!=null){
            if(cur.next.val==cur.next.next.val){
                int temp=cur.next.val;
                while(cur.next!=null&&cur.next.val==temp){
                    cur.next=cur.next.next;
                }
            }else{
                cur=cur.next;
            }
        }
        return ans.next;

    }
}

#240 搜索二维矩阵 II

从左下角看,往上是减小,往右是变大。

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix.length==0){
            return false;
        }
        int row=matrix.length;
        if(matrix[0].length==0){
            return false;
        }
        int col=matrix[0].length;
        for(int i=row-1,j=0;i>=0&&j<col;){
            if(matrix[i][j]>target){
                i--;
            }else if(matrix[i][j]<target){
                j++;
            }else{
                return true;
            }
        }
        return false;
    }
}
#162 寻找峰值

上坡必有坡顶,所以上坡的那一段一定有峰值(二分法原理)

class Solution {
    public int findPeakElement(int[] nums) {
        int left=0,right=nums.length-1;
        while(left<right){
            int mid=left+((right-left)>>1);
            if(nums[mid]>nums[mid+1]){
                right=mid;
            }else{
                left=mid+1;
            }
        }
        return right;

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值