20210805 summary of force deduction string questions

Posted by glence on Tue, 04 Jan 2022 13:15:57 +0100

Daily question 611: judge whether it is a triangle

My inherent impression is to use violence to solve, then timeout, and then sort the array and recalculate. It is passed, but it takes too long.

class Solution {
    public int triangleNumber(int[] nums) {
        int n = nums.length;
        if(n<3) return 0;
        int count = 0;
        Arrays.sort(nums);
        for(int i = 0 ;i<n-2;i++)
        {
            for(int j=i+1;j<n-1;j++)
            {
                int right = j+1;
                
                while(right<n)
                {
                    if(nums[i]+nums[j]>nums[right])
                        count++;
                    right++;
                }
            }
        }
        return count;
    }
 
}

Later, I read the comment. It is the fixed maximum, and then a left pointer and a right pointer.

class Solution {
    public int triangleNumber(int[] nums) {
        
        
        int n = nums.length;
        if(n<3) return 0;
        int count = 0;
        Arrays.sort(nums);
       
       for(int k = n-1;k>=2;k--)
       {
           int left = 0;
           int right = k-1;

           while(left<right)
           {
               if(nums[left]+nums[right]>nums[k])
               {
                   count+=right-left;
                   right--;
               }
               else 
               {
                   left++;
               }

           }
       }
        return count;
    }
 
}

At first, I didn't understand why count + = right left; Later, I learned that, because the order has been arranged, left right and K can be, so the number from left to right-1 can always be, that is, Num [left] + num [right] > num [k]. Compare their increasing number.

Force buckle question 802: find the final safe state (heavy)

At first glance, we know that this problem is recursive, but how to do it is not. After reading the comments, we use two arrays to mark whether it has been accessed and whether it is a safe point. Finally, add the safe points to the list.

class Solution {
    public List<Integer> eventualSafeNodes(int[][] graph) {
    
        List<Integer> list = new ArrayList<>();
        int n = graph.length;
        int[] flag = new int[n];//0 is not accessible. 1 is secure. 2 is not secure
        boolean visited[] =new boolean[n];

        for(int i = 0 ;i<n;i++)
        {
            dfs(graph,flag,visited,i);
        }

        for(int i = 0 ; i<n;i++)
        {
            if(flag[i]==1) list.add(i);
        }
        return list;

    }  
    boolean dfs(int[][] graph,int[] flag,boolean visited[],int start)
    {
        if(flag[start]!=0)
        {
            if(flag[start] == 1) return true;
            else return false;
        }
        boolean res = true;
        for(int i:graph[start])
        {
            if(visited[i]) return false;
            visited[i] = true;
            res = res&&dfs(graph,flag,visited,i);
            visited[i] = false;
        }

        if(res) flag[start] = 1;
        else flag[start] = 2;

        return res;
    }
}

I've done a lot of recursive problems before, but I still haven't done this problem. Hey, this exercise needs to be understood. You can't just copy it and forget it again.
The wrong place is for(int i:graph[start]). I began to write for (int i = 0; I < graph [strat]. Length; I + +), so it won't. such a length is the length of the column. We need to obtain the length of the row and the last if (res). We need to assign a value to the flag to see whether it is a safe point.

Force deduction question 443: compressed string

I saw this question and thought of using hashmap. I don't know how to use others. Write this first.

Map<Character,Integer> map = new HashMap<>();
        for(int i = 0 ;i<n;i++)
        {
            if(map.containsKey(chars[i]))
            {
                map.put(chars[i],map.get(chars[i])+1);
            }
            else
            {
                map.put(chars[i],1);
            }
        }
        int count = 0;
        for(Map.Entry entry:map.entrySet())
        {
            char key = (char) entry.getKey();
            count++;
            int value = (int) entry.getValue();
            String s = value+"";
            count+=s.length();
        }
        return  count;

After running, it is found that what is needed is a string. Although int is returned, it needs to be modified on the original chars. I failed to do this. Therefore, it should be calculated on the array. Try to continue modifying.
I wrote another one, but there is still a problem. I didn't modify it on the original array

class Solution {
    public int compress(char[] chars) {
        int n = chars.length;
        if(n==0) return 0 ;
        if(n==1) return 1;

        int left= 0;
        //int right = 0;

        StringBuilder sb = new StringBuilder();
        for(int i = 1;i<n;i++)
        {
            int count = 1;
            
           if(chars[left]==chars[i])    sb.append(chars[i]);
          
           //if(left==0&&chars[left]!=chars[i]) sb.append(chars[left]);
            

            while(i<n&&chars[left]==chars[i])
            {
                count++;
                i++;
            }
            if(count!=1) sb.append(count);
            left +=count; 
        }
        char s[] = sb.toString().toCharArray();
        for(int i = 0;i<s.length;i++)
        {
            chars[i] = s[i];
        }
        return s.length;

    }
}

There are still problems with this writing, so I'm going to look at the answers.
Seeing a comment is very similar to my idea.

class Solution {
    public int compress(char[] chars) {
        int n = chars.length;
        if(n==0) return 0 ;
        if(n==1) return 1;
       
        StringBuilder sb = new StringBuilder();
        int count = 1 ;
        char c = chars[0];
        sb.append(c);
        for(int i = 1 ;i<n;i++)
        {
            if(c==chars[i])
            {
                count++;
            }
            else
            {
                if(count!=1)
                {
                    sb.append(count);
                }
                c=chars[i];
                sb.append(c);
                count = 1;
            }
        }
        if(count!=1) //Last element
        {
            sb.append(count);
        }

        char s[] = sb.toString().toCharArray();
        for(int i = 0 ;i<s.length;i++)
        {
            chars[i]=s[i];
        }

        return s.length;
      
    }
}

Now let's look at the double pointer method:

class Solution {
    public int compress(char[] chars) {
        int n = chars.length;
        int read = 0 ;//read
        int write = 0;//write
        int cur = 0;//current location
        while(read<n)
        {
            while(read<n&&chars[read]==chars[write])
            {
                read++;
            }
            chars[cur++] =chars[write];
            if(read-write>1)
            {
                for(char c:String.valueOf(read-write).toCharArray())
                {
                    chars[cur++] = c;
                }
            }
            write = read;
        }
       return cur;
    }
}

The double pointer method converts read write into a string and adds it directly.

Force deduction question 8: string to integer

I've done this problem before. This time I'm still using if. If I can't judge it, I still have to go by bit by bit to see what it is and what character is used Isdigit() function to judge whether it is a number. I used s.charat (I) > '0' & & s.charat (I) < '9'. At first glance, it is OK, but 0 and number 9 are ignored. This question is more about details.

Question 13: Roman numerals to integers

This question was also done before. This time, I thought of using hashmap, but I made a mistake when dealing with special characters such as' IV '. After reading the comments, I found that those special characters can be replaced. Under normal circumstances, they gradually decrease from left to right. When the value of this character is less than the next character, it is sum - =. The other is + =.

Force deduction question 12: integer to Roman numeral

I've done this problem before. Why am I still thinking about using hashmap? For this problem, an array stores a string, an array stores int, and then num decreases all the time and the string increases all the time.
These questions have to be looked at later. If you don't look at them, you'll forget them.

summary

I didn't do many questions, and I was a little lax. After I finished every night, I didn't summarize and left directly, so I came to summarize the next morning. It's not very good
The first one is the daily question. I haven't done it for a long time. I've been practicing. The other one is cumbersome. I'm a little impatient. I've done three questions before, but I'm still stumbling when I write them. This is too low. Whether I can write them or not, I have to think first. Don't always look at the answers. It's not a good performance. Come on!

Topics: Java leetcode string