leetcode刷题记录四

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Viscu/article/details/82080989
1.convert-sorted-list-to-binary-search-tree

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
用一颗有序的数组建立一个二叉树,利用快慢指针找中点,左边就是他的左子树,右边就是他的右子树,dfs即可。

class _91{
    public TreeNode sortedListToBST(ListNode head) {
        return build(head,null);
    }
    private TreeNode build(ListNode head,ListNode tail){
        if(head==tail){
            return null;
        }
        ListNode slow=head;
        ListNode quick=head;
        while (quick!=tail&&quick.next!=tail){
            //利用快慢指针找中点 理论上quick.next!=tail&&quick.next.next!=tail也是可以的。
            slow=slow.next;
            quick=quick.next.next;
        }
        TreeNode root=new TreeNode(slow.val);
        root.left=build(head,slow);
        root.right=build(slow.next,tail);
        return root;
    }
}
2.recover-binary-search-tree

Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note:
A solution using O(n ) space is pretty straight forward. Could you devise a constant space solution?

1:并没有O(n),跑一遍存值排序再跑一遍中序遍历重新赋值。
class _92{
    ArrayList<Integer> alt;
    int i;
    public void recoverTree(TreeNode root) {
        alt=new ArrayList<Integer>();
        i=0;
        dfs(root);
        Collections.sort(alt);
        dfs1(root);
    }
    public void dfs(TreeNode root){
        if(root.left!=null){
            dfs(root.left);
        }
        alt.add(root.val);
        if(root.right!=null){
            dfs(root.right);
        }
    }
    public void dfs1(TreeNode root){
        if(root.left!=null){
            dfs1(root.left);
        }
        if(root.val!=alt.get(i)){
            root.val=alt.get(i);
        }
        i++;
        if(root.right!=null){
            dfs1(root.right);
        }
    }
}
法二:依旧是中序遍历,bst中序遍历结果是递增的,
我们记录下出现异常的两个位置,交换值即可。
import java.util.*;
public class Solution {
    private TreeNode fir,sec,pre;
    public void recoverTree(TreeNode root) {
        fir=sec=null;
        pre=null;
        dfs(root);
        if(fir!=null&&sec!=null){
            swap(fir,sec);
        }
    }
    private void swap(TreeNode fir,TreeNode sec){
        fir.val^=sec.val;
        sec.val^=fir.val;
        fir.val^=sec.val;
    }
    private void dfs(TreeNode root){
        if(root.left!=null){
            dfs(root.left);
        }
        if(pre!=null&&root.val<pre.val){
            if(fir==null){
                fir=pre;
            }
            sec=root;
        }
        pre=root;
        if(root.right!=null){
            dfs(root.right);
        }
    }
}
3.convert-sorted-array-to-binary-search-tree

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
数组,二分即可。

public class _94 {
    public TreeNode sortedArrayToBST(int[] num) {
        if(num.length==0){
            return null;
        }
        return build(0,num.length,num);
    }
    private TreeNode build(int st,int ed,int[] num){
        if(st==ed){
            return null;
        }
        int mid=st+(ed-st)/2;
        TreeNode root=new TreeNode(num[mid]);
        root.left=build(st,mid,num);
        root.right=build(mid+1,ed,num);
        return root;
    }

    public static void main(String[] args) {
        int[] a={1};
        System.out.println(new _94().sortedArrayToBST(a));
    }
}
4.partition-list

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given1->4->3->2->5->2and x = 3,
return1->2->2->4->3->5.
新建两个新的链表,一个按顺序存比x小的值,一个按顺序存大于等于x的值,最后把大的接小的后面即可。

class _95{
//新建两个新的链表,一个按顺序存比x小的值,一个按顺序存大于等于x的值,最后把大的接小的后面即可。
    public ListNode partition(ListNode head, int x) {
        ListNode big=new ListNode(-1);
        ListNode small=new ListNode(-1);
        ListNode cur=head;
        ListNode p=big;
        ListNode q=small;
        while (cur!=null){
            if(cur.val>=x){
                p=p.next=cur;
            }else{
                q=q.next=cur;
            }
            cur=cur.next;
        }
        q.next=big.next;
        p.next=null;
        return small.next;
    }

    public static void main(String[] args) {
        int[] a={1,4,3,2,5,2};
        ListNode node=InsertUtil.build(a);
        node=new _95().partition(node,3);
        InsertUtil.play(node);
    }
}
5、permutation-sequence

The set[1,2,3,…,n]contains a total of n! unique permutations.
By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):
“123”
“132”
“213”
“231”
“312”
“321”
Given n and k, return the k th permutation sequence.
Note: Given n will be between 1 and 9 inclusive.
dfs即可,从小到大dfs,记录走过多少个字符串,到达k,即为答案。

class _96{

    private boolean[] vis;
    private int[] f;
    private boolean flag;
    private String ans;
    private int ct;
    public String getPermutation(int n, int k) {
        vis=new boolean[10];
        f=new int[10];
        flag=false;
        ans=null;
        ct=0;
        dfs(n,k,0);
        return ans;
    }
    public void dfs(int n,int k,int pos){
        if(flag){
            return;
        }
        if(pos==n){
            ++ct;
            if(ct==k){
                StringBuilder sb=new StringBuilder();
                for (int i=0;i<n;++i){
                    sb.append(f[i]);
                }
                ans=sb.toString();
                flag=true;
            }
            return;
        }
        for (int i = 1; i <= n; i++) {
            if(!vis[i]){
                f[pos]=i;
                vis[i]=true;
                dfs(n,k,pos+1);
                vis[i]=false;
            }
        }
    }
    public static void main(String[] args) {
        System.out.println(new _96().getPermutation(2,1));
    }
}
6.spiral-matrix-ii

Given an integer n, generate a square matrix filled with elements from 1 to n 2 in spiral order.
For example,
Given n =3,
You should return the following matrix:
[
[ 1, 2, 3 ],
[ 8, 9, 4 ],
[ 7, 6, 5 ]
]
dir代表四个方向,ls,le代表左右边界,rs,re代表上下边界。

class _97{
    public int[][] generateMatrix(int n) {
        int t=n*n;
        int ct=1;
        int dir=0;
        int ls=0;
        int le=n-1;
        int rs=0;
        int re=n-1;
        int[][] marix=new int[n][n];
        while (ct<=t){
            dir=dir%4;
            switch (dir){
                case 0:
                    for (int i = ls; i <= le; i++) {
                        marix[rs][i]=ct++;
                    }
                    ++rs;
                    break;
                case 1:
                    for (int i = rs; i <= re; i++) {
                        marix[i][le]=ct++;
                    }
                    --le;
                    break;
                case 2:
                    for(int i = le; i >= ls; --i){
                        marix[re][i]=ct++;
                    }
                    --re;
                    break;
                case 3:
                    for(int i = re; i >= rs; --i){
                        marix[i][ls]=ct++;
                    }
                    ++ls;
            }
            ++dir;
        }
        return marix;
    }
}

7.spiral-matrix
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
For example,
Given the following matrix:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
You should return[1,2,3,6,9,8,7,4,5]
与上一题是一样的。

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] matrix) {
        if(matrix.length==0){
            return new ArrayList<Integer>();
        }
        ArrayList<Integer> ans=new ArrayList<Integer>();
        int total=matrix.length*matrix[0].length;
        int ct=1;
        int dir=0;
        int ls=0;
        int le=matrix[0].length-1;
        int rs=0;
        int re=matrix.length-1;
        while (ct<=total){
            dir=dir%4;
            switch (dir){
                case 0:
                    for (int i = ls; i <= le; i++) {
                        ans.add(matrix[rs][i]);
                        ++ct;
                    }
                    ++rs;break;
                case 1:
                    for (int i = rs; i <= re; i++) {
                        ans.add(matrix[i][le]);
                        ++ct;
                    }
                    --le;break;
                case 2:
                    for (int i = le; i >= ls; --i) {
                        ans.add(matrix[re][i]);
                        ++ct;
                    }
                    --re;break;
                case 3:
                    for (int i = re; i >= rs; --i) {
                        ans.add(matrix[i][ls]);
                        ++ct;
                    }
                    ++ls;
            }
            ++dir;
        }
        return ans;
    }
}
8.maximum-subarray

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array[−2,1,−3,4,−1,2,1,−5,4],
the contiguous subarray[4,−1,2,1]has the largest sum =6.
click to show more practice.
More practice:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
最大子段和,O(n)做法。

public class Solution {
    public int maxSubArray(int[] A) {
        int max=A[0];
        int sum=A[0];
        for (int i = 1; i < A.length; i++) {
            sum=Math.max(A[i],sum+A[i]);
            max=Math.max(max,sum);
        }
        return max;
    }
}
9.trapping-rain-water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given[0,1,0,2,1,0,1,3,2,1,2,1], return6.

能积水,必定是该pos左右两边都有墙,且比他高,如果我们找最近的左右两边比他高,那实现起来很麻烦,
所有要找突破口,就是先找最高的墙,那么只需要找左边比该pos高的墙或者右边比他高的墙即可。

public class Solution {
    public int trap(int[] A) {
       int maxIndex=0;
        int l=0;
        int r=0;
        int ans=0;
        int max=0;
        for (int i = 0; i < A.length; i++) { //找到最高的墙的index
            if(A[i]>max){
                maxIndex=i;
                max=A[i];
            }
        }
        for (int i = 0; i < maxIndex; i++) { //左边遍历,边遍历边找左边较高的墙
            if(l<A[i]){
                l=A[i];
            }else if(l>A[i]){
                ans+=l-A[i];
            }
        }
        for (int i = A.length-1; i > maxIndex; --i) { //右边遍历,边遍历边找右边比较高的墙
            if(r<A[i]){
                r=A[i];
            }else if(r>A[i]){
                ans+=r-A[i];
            }
        }
        return ans; 
    }
}
10.jump-game-ii

Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given array A =[2,3,1,1,4]
The minimum number of jumps to reach the last index is2. (Jump1step from index 0 to 1, then3steps to the last index.)
先预处理一遍,把第i个为能走到的最大坐标存起来。
我们从后往前处理,每次找到第一个能够大于等于目标值的坐标,
把找到的坐标更新为下一个目标值,一直找到目标值为起始位置坐标,即为最小步数。

class _101{
    public int jump(int[] A) {
        int[] b=new int[A.length];
        for (int i = 0; i < A.length; i++) {
            b[i]=i+A[i];
        }
        int ans=0;
        int end=A.length-1;
        while (true){
            for (int j = 0; j < end; j++) {
                if(b[j]>=end){
                    end=b[j]-A[j];
                    ++ans;
                    break;
                }
            }
            if(end==0){
                break;
            }
        }
        return ans;
    }
    public static void main(String[] args) {
        int[] a={2,3,1,1,4};
        System.out.println(new _100().jump(a));
    }
}
11.best-time-to-buy-and-sell-stock

Say you have an array for which the i th element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
先预处理一遍,prices[i]-prices[i-1]表示你该天能够获得利润。
然后跑一遍dp,最大字段和即可。

public class Solution {
   public int maxProfit(int[] prices) {
        if(prices.length==0){
            return 0;
        }
        int[] dp=new int[prices.length];
        for (int i = 1; i < prices.length; i++) {
            dp[i]=prices[i]-prices[i-1];
        }
        int max=0;
        int sum=0;
        for (int i = 1; i < prices.length; i++) {
            sum=Math.max(dp[i],sum+dp[i]);
            max=Math.max(sum,max);
        }
        return max;
    }
}
12.largest-rectangle-in-histogram
//思路:单调栈
//维护一个单调递增的栈,l,r代表该pos的左右边界(l,r为下标)
//例如:2,1,5,6,2,3
//2的左右边界为(0,0)即2在这个区间保持最小
//1就是(0,5)
//最后算面积就是(p.r+1-p.l)*p.h
class _103{
    static class area{
        int l;
        int r;
        int h;
        int index;
    }
    public int largestRectangleArea(int[] height) {
        area[] t=new area[height.length];
        Stack<area> st=new Stack<area>();
        for (int i = 0; i < height.length; i++) {
            t[i]=new area();
            t[i].l=i;
            t[i].index=i;
            t[i].h=height[i];
        }
        for (int i = 0; i < height.length; i++) {
            while (!st.isEmpty()&&st.peek().h>t[i].h){
                t[st.peek().index].r=i-1;
                t[i].l=st.peek().l;
                st.pop();
            }
            st.push(t[i]);
        }
        while (!st.isEmpty()){
            st.pop().r=height.length-1;
        }
        int max=0;
        for (int i = 0; i < height.length; i++) {
            max=Math.max(max,(t[i].r+1-t[i].l)*t[i].h);
        }
        return max;
    }

    public static void main(String[] args) {
        int[] a={2,1,5,6,2,3};
        System.out.println(new _103().largestRectangleArea(a));
    }
}
13.search-in-rotated-sorted-array

Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e.,0 1 2 4 5 6 7might become4 5 6 7 0 1 2).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.

思路:
遍历一遍,找到第一个pos[i]<pos[i-1];
以i为分界,对0-i-1进行二分,对iA.len进行二分
public class _104 {
    public int search(int[] A, int target) {
        if(A.length==0){
            return -1;
        }
        int lend=0;
        for (int i = 1; i < A.length; i++) {
            if(A[i]>A[i-1]){
                lend++;
            }else{
                break;
            }
        }
        int l=binary(A,target,0,lend);
        int r=-1;
        if(lend+1<=A.length-1){
            r=binary(A,target,lend+1,A.length-1);
        }
        if(l!=-1){
            return l;
        }
        return r;
    }

    private int binary(int[] arr,int target,int l,int r){
        while (l<=r){
            int mid=l+(r-l)/2;
            if(arr[mid]==target){
                return mid;
            }else if(arr[mid]>target){
                r=mid-1;
            }else{
                l=mid+1;
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        int[] a={3,1};
        System.out.println(new _104().search(a,1));
    }

}
14.search-in-rotated-sorted-array-ii

Follow up for “Search in Rotated Sorted Array”:
What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.
遍历一遍即可,可二分做。

class _105{
    public boolean search(int[] A, int target) {
        for (int i = 0; i < A.length; i++) {
            if(A[i]==target){
                return true;
            }
        }
        return false;
    }
}
15.two-sum

Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
利用HashMap,将target-num[i]的值存到map中,若map存在值=当前的pos值,那么就是所找答案。

class _106{
    public int[] twoSum(int[] numbers, int target) {
        Map<Integer,Integer> map=new HashMap<Integer, Integer>();
        for (int i = 0; i < numbers.length; i++) {
            if(map.containsKey(numbers[i])){
                return new int[]{map.get(numbers[i])+1,i+1};
            }
            map.put(target-numbers[i],i);
        }
        return null;
    }
}
16.add-two-numbers

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
这道题一开始没理解清楚…..emmmm.
其实意思就是: 243->342 564->465 342+465=807 ->708
意思就是他是翻转过来进行相加减的。
我们只需要把链表每个位为进行相加,大于10进1即可。

class _107{
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        if(l1==null){
            return l2;
        }
        if(l2==null){
            return l1;
        }
        int ans=0;
        ListNode dummy=new ListNode(-1);
        ListNode p=dummy;
        while (l1!=null||l2!=null||ans!=0){
            if(l1!=null){
                ans+=l1.val;
                l1=l1.next;
            }
            if(l2!=null){
                ans+=l2.val;
                l2=l2.next;
            }
            p=p.next=new ListNode(ans%10);
            ans/=10;
        }
        return dummy.next;
    }
}
17.integer-to-roman

Given an integer, convert it to a roman numeral.
Input is guaranteed to be within the range from 1 to 3999.
知道下面两个即可做。
int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] str = {“M”, “CM”, “D”, “CD”, “C”, “XC”, “L”, “XL”, “X”, “IX”, “V”, “IV”, “I”};

class _108 {
    public static String intToRoman(int num) {
        int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        String[] str = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < values.length; i++) {
            while (num>=values[i]) {
                num -= values[i];
                sb.append( str[i] );
            }
        }
        return sb.toString();
    }
    public static void main(String[] args) {
        System.out.println(intToRoman(3));
    }
}
18.roman-to-integer

Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.

map.put(‘I’, 1);
map.put(‘V’, 5);
map.put(‘X’, 10);
map.put(‘L’, 50);
map.put(‘C’, 100);
map.put(‘D’, 500);
map.put(‘M’, 1000);

从后往前遍历并存下最近的value.
IV=4,VI=6

import java.util.*;
public class Solution {
    public int romanToInt(String s) {
        Map<Character,Integer> map=new HashMap<Character,Integer>();
        map.put('I', 1);
        map.put('V', 5);
        map.put('X', 10);
        map.put('L', 50);
        map.put('C', 100);
        map.put('D', 500);
        map.put('M', 1000);
        int ans=0;
        int pv=0;
        int cv=0;
        for (int i = s.length()-1; i >= 0; --i) {
            cv=map.get(s.charAt(i));
            if(cv>=pv){
                ans+=cv;
            }else{
                ans-=cv;
            }
            pv=cv;
        }
        return ans;
    }
}

猜你喜欢

转载自blog.csdn.net/Viscu/article/details/82080989