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
两数之和
最简单的方法 遍历
思路:
做两次循环、跳过下标相同的情况。
由于题意为
- 必有解
- 唯一解
所以只要输出结果等于所给值就行。
复杂度 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: