Prefix Tree and Greedy Algorithm

1. Prefix Tree

Force Button Address

A Trie tree, also known as a dictionary tree, a Prefix Tree, a word lookup tree, or a key tree, is a multifork tree structure. Typical applications are for counting and sorting large numbers of strings (but not just strings)It has the advantage of minimizing unnecessary string comparisons and being more efficient than hash tables.

The core idea of Trie is space for time. Use the common prefix of the string to reduce the cost of query time in order to improve efficiency.

Trie trees also have their drawbacks, which are very memory intensive.

The basic structure is as follows:

[External chain picture transfer failed, the source may have anti-theft chain mechanism, suggest saving and uploading pictures directly (img-BzEzz8Kg8-163155554179776) (C:%5CUsers%5Cliuyuansong%5CDesktop%5C%E7%AC%94%E8%E8%E8%AE%B0%5C%5C%E5%89%8D%E7%BC%80%E6%E6%A0%91%E5%8C%8C%E8%B4%AA%E5%E5%E5%E5%E5%E5%EE5%83%EF%E7%E7%E7%E7%E7%E7%E7%E7%95.assets%5C1617808294645.png)]

The image above is a Trie tree representing a collection of keywords {"a", "to", "tea", "ted", "ten", "i", "in", "inn"}.

Basic properties of Trie trees:
1. The root node does not contain a character. Every child node except the root node contains a character.
(2) From the root node to a node, the characters that pass through the path are connected to form the corresponding string for that node.
(3) All the sub-nodes of each node contain different characters, which can be reused naturally.
(4) Characters that repeat continuously from the first character occupy only one node, such as to, and ten above. The repeating word t occupies only one node.

To implement a prefix tree, you need three variables, pass, end, nexts.

int pass indicates that by the number of times this node has passed, it is possible to determine that several of the joined strings are prefixed with'incoming pre'
int end denotes how many strings end with this node
TrieNode[] nexts; //The array holding the next node is not directly next node because it may be followed by more than one character

eg: next[0] ==null has no way to'a', next[0]!=Null has a way to'a'
eg: next[26] ==null has no way to'z', next[26]!=Null has a way to'z'

public class TrieTree {
    //Tree Node
    public static class TrieNode {
        int pass;  //By the number of times this node has passed, you can tell how many times a prefix of a string has passed
        int end; //How many strings end with this node
        TrieNode[] nexts;//The array holding the next node is not directly next node because it may be followed by more than one character
        //eg: next[0] ==null has no way to'a'next[0]!=Null has a way to'a'
        //eg: next[26] ==null has no way to'z'next[26]!=Null has a way to'z'
		
        TrieNode() {//Constructor
            pass = 0;
            end = 0;
            nexts = new TrieNode[26];   //Initialization array up to 26 letters
        }
    }

    public static class Trie{
        private TrieNode root;
        public Trie(){
            root = new TrieNode(); //Initialize the root node without data to make it a puppet node
        }

        //The process of building a prefix tree
        public void insert(String word){
            //String empty not handled
            if (word == null) return; 
            char[] chs = word.toCharArray();
            //Define a node to point to root
            TrieNode node = root;
            //Once you want to start hanging things on the root and stretch the road, start with ++, so the pass value on the root is how many words are entered
            node.pass++;
            for (char ch : chs) {
             //Converts a character to its path, subtracts'a'from ASCII, so index of a = 0, index of B = 1, and so on
                int index = ch - 'a';
                //If there is no node beneath it, that is, no road, create a new one
                if (node.nexts[index] == null)
                    node.nexts[index] = new TrieNode();
                
                /*If so, multiplex and move to the node specified by the next
                  The summary is that there are nodes that move directly to the next (extending down), and if not, create a new one and move again*/
                node = node.nexts[index];  
                
                node.pass++; //pass++ on node properties along the way for each extension
            }
            node.end++;  //End++ at the end of the loop indicates how many words end with that node
        }

        //Lookup words have been added several times
        public int search(String word){
            if (word == null) return 0;
            char[] chs = word.toCharArray();
            TrieNode node = root;
            for (char ch : chs) {
                int index = ch - 'a';  //Convert the characters a,b,c..To their corresponding 0, 1, 2, 3..
                //When the next point does not correspond (null), return 0. For example, if there is a path abc, you want to check abcd, this path does not (as long as it is interrupted), return 0
                if (node.nexts[index] == null)   return 0;
                
                node = node.nexts[index];
            }
            return node.end; //To the end is the number of times you have joined
        }

        //To delete a path is to pass--, go to the last node, and end--
        public void delete(String word){
            if (search(word)!=0){ //Check it again before you can continue deleting it
                char[] chs = word.toCharArray();
                TrieNode node =root;
                node.pass--; //Let the root node pass first--because a word has been deleted
                for (char ch : chs) {
                    int index = ch - 'a';
                    
                    /*Then the pass of the corresponding node is operated on -1, and after subtracting it, we can see if it is equal to 0. If it is 0, it means that no one is going to it anymore, then we need to set it to null and disconnect all the following*/
                    if (--node.nexts[index].pass == 0) {
                        node.nexts[index] = null;
                        return;
                    }
                    node = node.nexts[index];
                }
                //Now that everything is looping, the node is over. Remember to end--
                node.end--;
            }
        }

        //Several of the added strings are prefixed with'pre'
        public int preNums(String pre){
            if (pre == null) return 0;
            char[] chs = pre.toCharArray();
            TrieNode node = root;
            for (char ch : chs) {
                int index = ch - 'a';  //Convert the characters a,b,c..To their corresponding 0, 1, 2, 3..
                if (node.nexts[index] == null) {  //The next point has no corresponding (null) and returns 0
                    // For example, if you have a path that is abc and you want to check that the prefix is abcd, this path does not (as long as it is broken) and returns 0
                    return 0;
                }
                node = node.nexts[index];
            }
            //The pass to the end is the number of paths prefixed with prep
            return node.pass;
        }
    }
}

2. Greedy algorithm

The basic idea of greedy algorithm:
1. Establish a mathematical model to describe the problem.
2. Divide the solved problem into several subproblems.
3. Solve each subproblem to obtain the local optimal solution of the subproblem.
4. Combine the local optimal solution of the subproblem into a solution of the original problem.

The premise of the greedy strategy is that the local optimal strategy can lead to the global optimal solution, which is transitive.

Techniques often used in the implementation of greedy strategies:

1. Create a comparer to sort by a criterion

2. Build a comparer to compose a heap based on a standard

General framework of greedy algorithms:

Selection function select: This is the greedy strategy, which is the key to greedy law. It indicates which candidate has the best chance of forming a solution to the problem. The selection function is usually related to the target function. For example, in the problem of finding change, greedy strategy is to select the currency with the highest par value in the candidate set.
Constraint function constraint: Check if adding a candidate to the solution set satisfies the constraint condition. For example, in the change finding problem, the constraint function is the sum of the currencies selected at each step and the currencies paid, which does not exceed the amount of the change to be found.

Greedy(C) //C is the input set or candidate set of the problem
{
    S={ }; //Initial solution set is empty
    while (not solution(S)) //Set S does not form a possible solution to the problem
    {
      x=select(C); //Greedy selection in candidate set C
      if constraint(S, x) //Determine if constraints are satisfied when x is added to set S
           S=S+{x};
           C=C-{x};
     }
     return S;
}

A possible solution to the problem is composed of all solution elements.

1. Minimum dictionary order of strings

Description: Given an array of strs of type string, find a way to stitch all strings together so that they form a string with the smallest dictionary order.

/*For example ABC > AAA C < CDA C > Ba
  Wrong idea: a, B a<=b, a before placing or B before placing counter example: b, B a If this means that splicing should be B B a but actually B a B is the smallest
  Correct: a, B a.b<=b.a before placing, otherwise B before placing (.means splicing)
 */
public class lowestZiDianXu {
    
    public static String lowestString(String[] strs){
        if (strs == null || strs.length ==0){
            return "";
        }
        Arrays.sort(strs, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return (a + b).compareTo(b + a); //Returns 0 if the specified number is equal to the parameter. Returns -1 if the specified number is less than the parameter (in parentheses). Returns 1 if the specified number is greater than the parameter.
                //Comparators obj1 and obj2 are objects to compare. If the objects are equal, this method returns zero. If obj1 is greater than obj2, it returns a positive value. Otherwise, it returns a negative value.
            }
        });
        String res = "";
        for (int i = 0; i < strs.length; i++) {
            res = res + strs[i];  //Stitching
        }
        return res;
    }
}

2. Scheduling of activities

Description: Some items occupy a single room for announcement. A conference room cannot hold two announcements at the same time. Give you the start and end time of each item (give you an array, which contains a specific item), you can schedule the announcement and ask the conference room to give the most announcements. Return to this maximum number of announcements.

public class BestArrange {

    //The structure of the meeting
    public static  class Program{
        public int start;
        public int end;

        public Program(int start, int end) {
            this.start = start;
            this.end = end;
        }
    }

    public static  int bestArrange(Program[] programs,int start){  //Beginning Time
        Arrays.sort(programs, new Comparator<Program>() {
            @Override
            public int compare(Program o1, Program o2) {
                return o1.end - o2.end;  //Top Rank with End Time Ascending, End First
            }
        });
        int result = 0;
        for (int i = 0; i < programs.length; i++) {
            //The point in time at which the meeting is to be scheduled (the target point in time)<=The start of the meeting description can be arranged in a single row, perhaps idle for a while
            if (start <= programs[i].start){ 
                result++;
                start = programs[i].end;  //Update Target Time Point
            }
        }
        return result;
    }
}

3. Cut gold bars

DESCRIPTION: A gold bar cut in half takes the same amount of copper as the length. For example, a 20-length bar, which costs 20 coppers regardless of the two halves of the length of the cut. How can a group of people divide the whole bar into the least expensive ones? For example, given an array {10,20,30}The gold bars are divided into 10,20,30=60 parts. If you first divide the gold bars with a length of 60 into 10 and 50, it will cost 60, and then the gold bars with a length of 50 into 20 and 30, it will cost 50 and a total of 110 copper plates. If you first divide the gold bars with a length of 60 into 30 and 30, it will cost 60, and then the gold bars with a length of 30 into 10 and 20, it will cost 30; if you divide the gold bars with a length of 60, it will cost 30; if you divide the gold bars with a length of 60, it will cost 30; if90 bronze plates.

Enter an array to return the minimum cost of splitting

Think: Small root heap, take two from the top each time, add them up and put them back until there is only one left in the priority queue.

//This is done with a small root heap
    public static  int LessMoney(int[] arr){
        PriorityQueue<Integer> pQ = new PriorityQueue<>();
        //Put all the data in the little root heap first
        for (int i = 0; i < arr.length; i++)
            pQ.add(arr[i]);
        int sum = 0;
        int curr = 0;
        while (pQ.size()>1){
            curr = pQ.poll() + pQ.poll();
            sum += curr;
            pQ.add(curr);
        }
        return sum;
    }

4. Maximum amount of money you can earn from doing projects

Input: Positive array costs Positive array profits Positive k Positive W

Meaning: costs[i] denotes the cost profits[i] of Item i, which means the money (profit) that Item I can make after deducting expenses.

k means you can only do up to k projects W means your initial capital

Description: The immediate benefits you get when you finish a project can support you to go to the next project. Output: The maximum amount of money you end up earning.

Idea: Put all projects const in a small root heap (lock them), then pop up all projects with costs less than or equal to the funds at this time in the locked small root heap, and after pop-up, place the profits of the pop-up projects in a large root heap (sorted by profit order)

public class IPO {
    public static  class  IPONode{
        public int costs;
        public int profits;

        public IPONode(int costs, int profits) {
            this.costs = costs;
            this.profits = profits;
        }
    }

    public static  class MinCostComparator implements Comparator<IPONode>{
        @Override
        public int compare(IPONode o1, IPONode o2) {
            return o1.costs - o2.costs;
        }
    }

    public static  class  MaxProfitsComparator implements  Comparator<IPONode>{

        @Override
        public int compare(IPONode o1, IPONode o2) {
            return o2.profits - o1.profits;
        }
    }
    
    public static  int findMaxcCapital(int k,int W,int[] Costs,int[] Profits){
        IPONode[] nodes = new IPONode[Profits.length];//Costs does, because they appear in pairs
        //Package project price and profit first
        for (int i = 0; i < Profits.length; i++) 
            nodes[i] = new IPONode(Costs[i], Profits[i]);
        
        //Create two priority queues: profits big root heap and const small root heap
        PriorityQueue<IPONode> maxProfitsQ = new PriorityQueue<>(new MaxProfitsComparator());
        PriorityQueue<IPONode> minCostsQ = new PriorityQueue<>(new MinCostComparator());
        //To put everything first in the smallest cost means to put everything first in the small root heap
        for (int i = 0; i < nodes.length; i++) 
            minCostsQ.add(nodes[i]);
        
        //Since there are only k opportunities
        for (int i = 0; i < k; i++) {
            //Minimum cost queue is not empty (locked) &&Existing capital W >=Costt of all top items can enter maximum profit Q (unlocked). This means that all items with costs less than or equal to the funds at this time will be ejected and put into the big root heap
            while (!minCostsQ.isEmpty() && W >= minCostsQ.peek().costs){
                maxProfitsQ.add(minCostsQ.poll());
            }
            //Once the capital chain can't keep up (maxQ is empty, it means too little money, the project can't be done), return to the existing capital W
            if (maxProfitsQ.isEmpty())
                return W;
            //Otherwise, capital is the top profit of w+big root heap
            W = W + maxProfitsQ.poll().profits;
        }
        return W;
    }
}

5. Boat crossing river

An array arr, length N and each value is positive, representing the weight of N individuals. Given a positive limit, it represents the weight of a ship. Each ship can only be two persons at most; the weight of passengers cannot exceed the limit. It will take at least a few boats to return if N individuals are crossing the river at the same time.

Think: Greedy, the lightest and heaviest groups are ordered first, then the greedy double pointer should first sort the weight of people, and then compare the weight of the largest person and the smallest person, and if they are overweight, give the heaviest ship and then compare it with the second largest person. Until all is done.

 public int getBoat(int[] arr, int limit) {
        //Sort your weight first
        Arrays.sort(arr);
        int i = 0,j = arr.length - 1;
        int boatSum = 0;
        while(i <= j) {
            //If you're in the middle, there's only one person left and this person has a single boat
            if(i == j) {
                boatSum++;
                break;
            }
            //Give them a double pointer movement if the lightest and heaviest can form a group
            if(arr[i] + arr[j] <= limit) {
                boatSum++;
                i++;
                j--;
            } 
            else {//If the lightest and heaviest can't be grouped together, give weight to a single ship j--
                //Because you're the heaviest and lightest I can't match you, you can only take a boat by yourself
                boatSum++;
                j--;
            }
        }
        return boatSum;
    }

6. Swing Sequence

Force Button Address

  public int wiggleMaxLength(int[] nums) {
        if(nums.length<=1) return nums.length;
        int res=1;//The rightmost end is a peak
   //Record whether the previous pair is positive or negative If the previous positive diff is also positive, continue on the same slope or res++.
   //continue if the previous negative current diff is also negative
        int preDiff=0;
        for(int i=0;i<nums.length-1;i++){
            int diff=nums[i+1]-nums[i];
              //Explanation that a peak or valley has been encountered because the current is positive and the front may be flat or the valley has been encountered
            if((diff>0 && preDiff<=0) || (diff<0 && preDiff>=0)){
                res++;
                preDiff=diff; 
            }
        }
        return res;
    }

7. Jump Game

Lower

 public boolean canJump(int[] nums) {
       /* //dp[i]Represents whether to jump to the current position
        boolean[] dp=new boolean[nums.length];
        dp[0]=true;
        for(int i=1;i<nums.length;i++){
            for(int j=i-1;j>=0;j--){
                //Can jump to that position and that position can jump here
                if(dp[j] && nums[j]+j>=i){
                      dp[i]=true;
                      break;
                }
            }
        }
        return dp[nums.length-1];*/
        if (nums.length == 1) return true; // Only one element is achievable
        int cover=nums[0];//Maximum distance covered by the first element
        for(int i=1;i<nums.length;i++){
            //Return directly if the maximum distance is no longer at the current location
            if(cover < i) return false;
            //If so, see if the maximum distance can be enlarged
            cover=Math.max(cover,nums[i]+i);
        }
        return true;
    }

senior No matter how greedy you jump, the coverage must be able to jump to, increase the coverage by the most steps. Once you cover the end point, you get the most steps! This requires statistics of two coverages, the coverage of the current steps is the most and the coverage of the next steps is the most

	 public int jump(int[] nums) {
        if(nums.length==1) return 0;
        /* dynamic programming
        boolean[] can=new boolean[nums.length];
        int[] dp=new int[nums.length];
        dp[0]=0;
        can[0]=true;
        for(int i=1;i<nums.length;i++){
            dp[i]=Integer.MAX_VALUE;
            for(int j=i-1;j>=0;j--){
                //Can jump to that position and that position can jump here
                if(can[j] && nums[j]+j>=i){
                    dp[i]=Math.min(dp[i],dp[j]+1);
                    can[i]=true;  
                }
            }
        }
        return dp[nums.length-1];*/
        int curDistance = 0; // Maximum distance currently covered
        int res = 0; 
        int nextDistance = 0; // The furthest distance covered by the next step
        for (int i = 0; i < nums.length - 1; i++) {
            nextDistance = Math.max(nums[i] + i, nextDistance); // Update the furthest distance covered by the next step
            if (i == curDistance) { // Currently is the furthest distance covered
                curDistance = nextDistance; // Update current maximum coverage distance
                res++;
            }
        }
        return res;
    }

8. Gas stations

Force Button Address The analogy is that there are n stations on a circular road; each station has a good person or a bad person; the good person gives you money and the bad person charges you for the toll. If you don't have enough money to pay the toll, the bad person chops you to death. Ask: From which station can you walk around and live back to your starting point?

First of all, consider the case that if all the good people give you less than the bad people's toll combined, there will always be a time when you don't have enough money to pay the toll and your end result will be chopped up.

Choose the right place if you have enough money. If you choose a start at random, then you will definitely start with a site with good people, because at the beginning you had no money and the bad people could only be chopped to death; now you start at the start, reach the end of a site, and be chopped to death by the bad people at the end of the site, you are[start, end] doesn't have enough money to pay the end-point bad person's toll because the start site is a good person, so at (start, end) If you start at any point in the document, you will save less money than you do now, or will be chopped down by the bad guys at the end site. So you read the file again and make smart choices to start at end+1 and continue your solemn journey. Finally one day, you find that you have reached the last site without being chopped down.

At this point of thought, I'm moving on, and I don't have enough money to keep you going to Start? Of course, since it was judged at the beginning that the amount of money a good person gives you is greater than or equal to the toll a bad person needs, and the money you've saved now is enough to pay the toll a bad person charges you

class Solution {
    //Method 2 o(n)
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int gasSum=0;
        //gas[i]-cost[i] represents the current position to the next position The remaining oil does not want to open a new array I've just overwritten the previous value here
        for (int i = 0; i < gas.length; i++){
            gas[i]=gas[i]-cost[i];
            gasSum+=gas[i];
        }
        if(gasSum<0) return -1;//If the total remaining oil is less than 0, you can't run at all.
        int sum=0,start=0;
        //Explaining that you can run away from the topic also means that you have a unique solution
        for (int i = 0; i < gas.length; i++) {
            sum+=gas[i];
            if(sum<0){
                start=i+1;
                sum=0;
            }
        }
        return start;
    }
}

9. Candy Divide (Cowdriver Focus)

Force buckle Cowdriver This question must be to determine the sides before determining another one, for example, the left side of each child, and then the right side. If both sides are considered together, one dimension will be determined before another dimension is determined.

Determine the right-to-left situation (traverse from front to back) and then the left-to-right situation (from back to front)

Be sure to take a large value from back to front, so take the number of need[i + 1] + 1 and need[i]. Only need[i] takes the most to keep both the number of left need[i - 1] and the number of right need[i + 1]

 public int candy (int[] arr) {
        int[] need=new int[arr.length];
        need[0]=1;//Default first point 1 candy
        //From left to right, find the best solution to assign when the right side is larger than the left side
        for(int i=1;i<arr.length;i++){
            //Bigger than the front is one more candy
            if(arr[i]>arr[i-1])
                need[i]=need[i-1]+1;
            else need[i]=1;//Divide up a candy if it is less than or equal to the front    
        }
        //Go back and forth to find the best solution when the left side is larger than the right side
        for(int i=arr.length-2;i>=0;i--){
            //Larger than the latter is one more candy than the latter and two more candy than the former is enough to satisfy the instructions.
            if(arr[i]>arr[i+1])
               need[i]=Math.max(need[i],need[i+1]+1);  
        }
        int res=0;
        for(int num:need)
            res+=num;
        return res;
    }

10. Rebuild Queues Based on Height

Force Button Address : Consider one dimension before the other directly inserting according to the subscript when using the same two dimensions

	public int[][] reconstructQueue(int[][] people) {
        //Height Ranking from High to Low
        Arrays.sort(people, new Comparator<int[]>() {
            public int compare(int[] person1, int[] person2) {
                if (person1[0] != person2[0]) 
                    return person2[0] - person1[0];
                 else 
                    return person1[1] - person2[1];
            }});
        List<int[]> ans = new ArrayList<int[]>();
        for (int[] person : people) {
            ans.add(person[1], person);
        }
        return ans.toArray(new int[ans.size()][]);
    }

11. Arrow balloons (11-14 are all interval greedy)

Force Button Address

 public int findMinArrowShots(int[][] points) {
        //Arrange from small to large
        Arrays.sort(points, (o1, o2) -> o1[0]-o2[0]);
        int res=1;//Less need for Musk Arrow
        for (int i = 1; i < points.length; i++) {
            //The second and first cannot be touched, the first needs to be shot alone
            if(points[i][0]>points[i-1][1]) res++;
            else //Ball i and ball i-1 coincide next to interval to update coincident right boundary
                points[i][1]=Math.min(points[i-1][1],points[i][1]);
        }
        return res;
    }

12. Non-overlapping intervals

Force buckle : Processing repetition intervals in the same order as above

 public int eraseOverlapIntervals(int[][] intervals) {
        //Arrange from small to large
        Arrays.sort(intervals,(o1, o2) -> o1[0]-o2[0]);
        int res=0,preEnd=intervals[0][1];
        for (int i = 1; i < intervals.length; i++) {
            //Continue updating preEnd end position coordinates if second and first are not contaminated
            if(intervals[i][0]>=preEnd) {
                preEnd=intervals[i][1];
            }
            else {//If i and i-1 coincide next to an interval, delete the one with the longest interval length
                preEnd=Math.min(preEnd,intervals[i][1]);
                res++;
            }  
        }
        return res;
    }

13. Section letter

Force buckle : counts the position of the last occurrence of each character, then traverses the character from the beginning, and updates the character's farthest occurrence subscript. If the character's farthest occurrence location subscript and the current subscript are equal, the split point is found

   public List<Integer> partitionLabels(String s) {
        int[] map=new int[26];//a..z
        //Count the farthest distance each character appears
        for (int i = 0; i < s.length(); i++)
            map[s.charAt(i)-'a']=i;
        List<Integer> res = new ArrayList<>();
        int right=0,start=0;
        for (int i = 0; i < s.length(); i++) {
            int len=map[s.charAt(i)-'a'];//Get the farthest distance of the current character
            right=Math.max(len,right);//Take the furthest distance
            // If you've reached the last length you can divide at your current location
            if(i==right){
                res.add(i-start+1);
                start=i+1;//Start a new series of divisions
            }
        }
        return res;
    }

14. Consolidation interval (bull focus)

Force buckle Cowdriver

//Force button answer
public int[][] merge(int[][] intervals) {
        //Sort by starting position
        Arrays.sort(intervals,(o1,o2)->o1[0]-o2[0]);
        List<int[]> list=new ArrayList<>();
        int start=intervals[0][0],preEnd=intervals[0][1];
        for (int i = 1; i < intervals.length; i++) {
            //When two intervals overlap, merge them and update the rightmost boundary of the merged interval
            if(intervals[i][0]<=preEnd){
                intervals[i][1]=Math.max(intervals[i][1],preEnd);
                preEnd=intervals[i][1];
            }
            else {//Add i-1 without overlapping
                list.add( new int[]{start,preEnd});
                //Re-update start and end locations
                start=intervals[i][0];
                preEnd=intervals[i][1];
            }
        }
        list.add( new int[]{start,preEnd});//Add the last group
        return list.toArray(new int[0][]);
    }
//Cowdriver Answer
 public ArrayList<Interval> merge(ArrayList<Interval> intervals) {
        //Sort by interval initial order
        Collections.sort(intervals,(( o1,o2) -> o1.start-o2.start));
        ArrayList<Interval> res= new ArrayList<>();
        if(intervals.size()==0) return res;
        int start=intervals.get(0).start,preEnd=intervals.get(0).end;
        for (int i = 1; i < intervals.size(); i++) {
            Interval curInterval = intervals.get(i);
            //Update the farthest distance the coincidence can reach if the current start is less than the previous end note encounters coincidence
            if(curInterval.start<=preEnd)
                preEnd=Math.max(preEnd,curInterval.end);
            else {//Explanation does not coincide then add element
                res.add(new Interval(start,preEnd));
                //Start a new interval
                start=curInterval.start;
                preEnd=curInterval.end;
            }
        }
        res.add(new Interval(start,preEnd));
        return res;
    }

();
if(intervals.size()==0) return res;
int start=intervals.get(0).start,preEnd=intervals.get(0).end;
for (int i = 1; i < intervals.size(); i++) {
Interval curInterval = intervals.get(i);
//Update the farthest distance the coincidence can reach if the current start is less than the previous end note encounters coincidence
if(curInterval.start<=preEnd)
preEnd=Math.max(preEnd,curInterval.end);
else {// description does not coincide then add element
res.add(new Interval(start,preEnd));
//Start a new interval
start=curInterval.start;
preEnd=curInterval.end;
}
}
res.add(new Interval(start,preEnd));
return res;
}

Tags: Java Algorithm data structure

Posted on Tue, 14 Sep 2021 00:20:44 -0400 by cheese