codetop高频(2)
三数之和
注意先排序,然后第一个位置重复了跳过,里面重复了跳过
注意指针不要越界。
class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>>ans=new ArrayList<>();Arrays.sort(nums);int pre=nums[0]-1;int len=nums.length;for(int i=0;i<len-2;i++){if(nums[i]==pre)continue;pre=nums[i];for(int j=i+1,k=len-1;j<k;){int sum=nums[i]+nums[j]+nums[k];if(sum>0)k--;else if(sum<0)j++;else{ans.add(Arrays.asList(nums[i],nums[j],nums[k]));while(j<k&&nums[j]==nums[j+1])j++;j++;}}}return ans;}
}
最大子数组和
使用在线处理算法,前面的为负数就丢掉。
也可以用dp
class Solution {public int maxSubArray(int[] nums) {int sum=Integer.MIN_VALUE;int pre=0;for(int i:nums){pre+=i;sum=Math.max(sum,pre);if(pre<0)pre=0;}return sum;}
}
合并两个有序链表
一个循环判断即可,比较当前节点的值小的放进来,然后移动两个指针。
初始化一个头结点,和一个新链表指针。
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode hh=new ListNode(0);ListNode pre=hh;while(list1!=null||list2!=null){int lnode=list1!=null?list1.val:200;int rnode=list2!=null?list2.val:200;if(lnode<rnode){pre.next=list1;list1=list1.next;}else{pre.next=list2;list2=list2.next;}pre=pre.next;}return hh.next;}
}
手撕快速排序
主函数直接调用,quicksort分左右两侧遍历,不稳定,元素相等会交换位置。
还有swap函数,注意i,j,l,r的大小关系
class Solution {public int[] sortArray(int[] nums) {quicksort(0,nums.length-1,nums);return nums;}void swap(int i,int j,int []nums){int t=nums[i];nums[i]=nums[j];nums[j]=t;}void quicksort(int l,int r,int []nums){if(l>=r)return ;int x=nums[(l+r)/2],i=l-1,j=r+1;while(i<j){do i++;while(nums[i]<x);do j--;while(nums[j]>x);if(i<j)swap(i,j,nums);}quicksort(l,j,nums);quicksort(j+1,r,nums);return ;}
}
最长回文子串
dp(最佳写法,还有中心扩散法但不如dp)
<2直接返回,默认最小值为1,dp[i][j]表示i到j的字符串是否回文
如果i==j并且字符串长度小于等于3(2、3长度回文)或i-1==j+1(3以上长度回文)就让dp为true
class Solution {public String longestPalindrome(String s) {if(s.length()<2)return s;int len=s.length();int ansStart=0;int ansEnd=0;int max=1;boolean dp[][]=new boolean[len][len];for(int i=1;i<len;i++){for(int j=0;j<i;j++){if(s.charAt(i)==s.charAt(j)&&(i-j<=2||dp[i-1][j+1])){ dp[i][j]=true;if(i-j+1>max){ansStart=j;ansEnd=i;max=i-j+1;}}}}return s.substring(ansStart,ansEnd+1);}
}