acm刷题记录(2020.3.11)

Leetcode 1013
将数组分为三个相等的部分
题目
思路:一个整数数组之和可以被分为三个相等的部分
说明Sum % 3 必然为0。
此时构建一个头指针p,尾指针k。
当数组0-p之和为sum/3、k-len之和为sum/3 且k-p>1
则必有 数组k-p之和为sum/3。
即该数组可以被分为相等的三部分。

复杂度o(n)

错题经验:
一开简单的以为做个计数器能识别两个sum/3就可以了。
但是 面对1,-1,1,-1行不通。

Code:
在这里插入图片描述
在这里插入图片描述
leetcode 1
两数之和
在这里插入图片描述
最简单的方法 遍历
思路:
做两次循环、跳过下标相同的情况。
由于题意为

  1. 必有解
  2. 唯一解
    所以只要输出结果等于所给值就行。
    复杂度 o(n²)
    Code:
class Solution {
    public int[] twoSum(int[] nums, int target) {
    for(int i=0;i<nums.length;i++)
    {
        for(int j=0;j<nums.length;j++)
        {
            if(i==j) {}
            else
                if(nums[i]+nums[j]==target) return new int[] {i,j};
        }
    }
    return null;
    }
}

高效的算法是
由于 trage-当前值a 得到 唯一值b
在一次遍历过程中 必然有一个b在a之前。
将之前的值存入哈希容器,由于哈希容器的查询复杂度为o(1)
所以该算法复杂度为 o(n)

code:

class Solution {
    public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for(int i=0;i<nums.length;i++)
    {
        int value=target-nums[i];
        if(map.containsKey(value))
        {
            return new int[] {map.get(value),i};
        }
        map.put(nums[i],i);
    }
    return null;
    }
}

在这里插入图片描述

leetcode 2
两数相加
在这里插入图片描述
此题考查链表操作,题目不难
注意的地方在进位上

code:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode l3=new ListNode(-1);
        ListNode l=l3;
        int s3=0;
        int k=0;
        int p=0;
        while(true)
        {
            int s1=0;
            int s2=0;
            s1=l1.val;
            s2=l2.val;
            int sum=0;//
            sum=s1+s2+s3;
            if(sum>9)
            {
                s3=sum/10;
                if(l3.val==-1)
                {
                    l3.val=sum%10;
                }
                else
                {
                l3.next=new ListNode(sum%10);
                l3=l3.next;
                }
            } 
            else
            {
                s3=0;
                if(l3.val==-1)
                {
                    l3.val=sum;
                }
                else
                {
                l3.next=new ListNode(sum);
                l3=l3.next;
                }
            }
        if(l1.next!=null) l1=l1.next;
        else {l1.val=0; k=1;}
        if(l2.next!=null) l2=l2.next; 
        else {l2.val=0; p=1;}
        if(s3==0&&k==1&&p==1) break;
        }
        return l;
    }
}

在这里插入图片描述leetcode 3
无重复字符的最长子串
在这里插入图片描述
此题我的思路为
用容器记录子串的字符和位数
当下一字符遇到相同字符时,子串长度=下一位-重复位 ,容器删去重复位前的键值对
若没遇到则子串长度+1

code:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character,Integer> map=new  HashMap<>();
        int maxlen=0;
        int len=0;
        for(int i=0;i<s.length();i++)
        {
           if(map.containsKey(s.charAt(i)))
           {
               int p=map.get(s.charAt(i));
               len=i-p;
               map=new HashMap<>();
               for(int j=p+1;j<=i;j++)
               {
                   map.put(s.charAt(j),j);
               }
           }
           else
           {
               len++;
               map.put(s.charAt(i),i);
           }
           if(len>maxlen) maxlen=len;
        }
        return maxlen;
    }
}

在这里插入图片描述
这个算法我看了半天才知道为什么效率这么低
因为我在覆盖键值对时浪费了不少时间其实可以不覆盖,通过比较位数判断重复字符的位是否在该子串的前面。
改进后
code:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character,Integer> map=new  HashMap<>();
        int maxlen=0;
        int len=0;
        int left=0;
        for(int i=0;i<s.length();i++)
        {
           if(map.containsKey(s.charAt(i)))
           {
               if(map.get(s.charAt(i))>=left)
               {
               int p=map.get(s.charAt(i));
               len=i-p;
               map.put(s.charAt(i),i);
               left=p;
               }
               else
               {
                   len++;
               map.put(s.charAt(i),i);
               }
           }
           else
           {
               len++;
               map.put(s.charAt(i),i);
           }
           if(len>maxlen) maxlen=len;
        }
        return maxlen;
    }
}

在这里插入图片描述
leetcode 12
整数转罗马数字
在这里插入图片描述
本身没有难度,考察字符串操作

code:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值