Java数据结构学习笔记

版权声明:本文纯属作者口胡,欢迎转载 https://blog.csdn.net/TQCAI666/article/details/87924159

语法杂记

排序

  • 数组排序
    Arrays.sort(arr);
  • 集合升序
    Collections.sort(list);
  • 集合降序
  1. 匿名类
Collections.sort(list, new Comparator<Integer>() {
    public int compare(Integer o1, Integer o2) {
        return o2 - o1;
    }
});//使用Collections的sort方法,并且重写compare方法
  1. 直接调包
Collections.sort(list,Collections.reverseOrder());
  1. 重现Comparator接口
    对于没有在类的内部实现Comparable接口的类, 就只能在外部实现Comparator接口, 然后当做参数传给相关的排序函数.
    class IntegerComparator implements Comparator<Integer>{
        @Override
        public int compare(Integer t0, Integer t1) {
            return t1.intValue()-t0.intValue();
        }
    }
    //调用
    Collections.sort(list, new IntegerComparator());
  • 类的排序

实现Comparable接口
对于类的多个成员变量进行比较, 优先级大的先比较, 优先级小的后比较, 在优先级大的相同时再考虑低优先级的特殊情况.

class Student implements Comparable<Student>{
    String name;int credit;int id;
    @Override
    public int compareTo(Student o) {
        if(!this.name.equals(o.name))
            return this.name.compareTo(o.name);
        else if(this.id!=o.id)
            return this.id-o.id;
        else
            return this.credit-o.credit;
    }
}

List

快速初始化List

        Integer array[]=new Integer[]{1,2,3};
        List<Integer> list;
        list= Arrays.asList(array);

HashSet

类似Python的get方法

default V getOrDefault(Object key, V defaultValue) 

让一个类的对象能装入HashSet

  • 重写equals和hashCode函数
    @Override
    public boolean equals(Object o) {
        if(o instanceof Student){
            Student s=(Student)o;
            if(this.name.equals(s.name) && this.credit==s.credit  &&  this.id==s.id)
                return true;
        }
        return false;
    }
List l=Arrays.asList(new Integer[] {1,2,3});
  1. 类型修饰必须是List或者List<Integer>而不是ArrayList, 因为List是父类
  2. 必读是new Integer, 而不是int

数组

两数之和

https://leetcode-cn.com/problems/two-sum/

  • 我的代码:
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int n=nums.length;
        int[] ret=new int[2];;
        solve:
        for(int i=0;i<n-1;i++){
            for(int j=i+1;j<n;j++){
                if(nums[i]+nums[j]==target){
                    
                    ret[0]=i;
                    ret[1]=j;
                    break solve;
                }
            }
        }
        return ret;
    }
}
  • 官方代码:
public int[] twoSum(int[] nums, int target) {
    for (int i = 0; i < nums.length; i++) {
        for (int j = i + 1; j < nums.length; j++) {
            if (nums[j] == target - nums[i]) {
                return new int[] { i, j };
            }
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}
  • 笔记:
  1. 临时返回一个匿名的数组: return new int[] { i, j };
  2. 如果不能在循环中返回, 则抛出异常: throw new IllegalArgumentException("No two sum solution"); , 也就是临时新建一个匿名的异常类IllegalArgumentException

线性表

三数之和

  • 讨论区AC代码
class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        nums.sort()
        res =[]
        i = 0
        for i in range(len(nums)):
            if i == 0 or nums[i]>nums[i-1]:
                l = i+1
                r = len(nums)-1
                while l < r:
                    s = nums[i] + nums[l] +nums[r]
                    if s ==0:
                        res.append([nums[i],nums[l],nums[r]])
                        l +=1
                        r -=1
                        while l < r and nums[l] == nums[l-1]:
                            l += 1
                        while r > l and nums[r] == nums[r+1]:
                            r -= 1
                    elif s>0:
                        r -=1
                    else :
                        l +=1
        return res
        
  • 我的超时代码
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ret=new ArrayList<>();//菱形语法
        int n=nums.length;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                for(int k=j+1;k<n;k++){
                    if(nums[i]+nums[j]+nums[k]==0){
                        List<Integer> tmp=new ArrayList<>();
                        tmp.add(nums[i]);tmp.add(nums[j]);tmp.add(nums[k]);
                        Collections.sort(tmp);
                        if(!ret.contains(tmp))
                            ret.add(tmp);
                    }
                }
            }
        }
        return ret;
    }
}
  • 可以巧妙避免重数据的Java代码
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ret=new ArrayList<>();//菱形语法
        int n=nums.length;
        Arrays.sort(nums);//排序
        for(int i=0;i<n;i++){
            if(i==0 || nums[i]>nums[i-1]){//确保唯一性(遍历中的首数字是唯一的)
                int l=i+1;
                int r=n-1;
                while(l<r){//two point 思想
                    int s=nums[i]+nums[l]+nums[r];
                    if(s==0){
                        List record=Arrays.asList(new Integer[] {nums[i],nums[l],nums[r]});
                        ret.add(record);
                        //找到一个解之后,必须把其余所有解找完, 但是要确保不能重复
                        r--;l++;
                        while(l<r && nums[r]==nums[r+1])
                            r--;
                        while(l<r && nums[l]==nums[l-1])
                            l++;
                    }else if(s<0){
                        l++;
                    }else if(s>0){
                        r--;
                    }
                }
            }
        }
        return ret;
    }
}
  • 简单粗暴去重
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        HashSet<List<Integer>> ret=new HashSet<>();//菱形语法
        int n=nums.length;
        Arrays.sort(nums);//排序
        for(int i=0;i<n;i++){
            int l=i+1;
            int r=n-1;
            while(l<r){//two point 思想
                int s=nums[i]+nums[l]+nums[r];
                if(s==0){
                    List record=Arrays.asList(new Integer[] {nums[i],nums[l],nums[r]});
                    ret.add(record);
                    r--;l++;
                }else if(s<0){
                    l++;
                }else if(s>0){
                    r--;
                }
            }
        }
        List<List<Integer>> ans=new ArrayList<>();
        for(List<Integer> i:ret){
            ans.add(i);
        }
        return ans;
    }
}

时间性能大打折扣
在这里插入图片描述

链表

两数相加

/**
 * 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) {
        int carry=0;//进位
        int v1,v2;
        ListNode ans=new ListNode(0);
        ListNode nd=ans;
        ListNode pre=new ListNode(0);
        while(l1!=null || l2!=null || carry!=0){
            if(l1!=null){
                v1=l1.val;
                l1=l1.next;
            }else{
                v1=0;
            }
            if(l2!=null){
                v2=l2.val;
                l2=l2.next;
            }else{
                v2=0;
            }
            
            int v=(v1+v2+carry);
            nd.val=v%10;
            carry=v/10;
            nd.next=new ListNode(0);
            pre=nd;
            nd=nd.next;
            
        }
        pre.next=null;
        return ans;
    }
}

排序

合并区间

https://leetcode-cn.com/problems/merge-intervals

class Solution {
    private class IntervalComparator implements Comparator<Interval>{

		@Override
		public int compare(Interval i1, Interval i2) {
			return i1.start-i2.start;
		}
		
	}
    public List<Interval> merge(List<Interval> intervals) {
        if(intervals==null||intervals.size()<=1) {
			return intervals;
		}
		LinkedList<Interval> list = new LinkedList<>();
		Collections.sort(intervals, new IntervalComparator());
		
		for (Interval interval : intervals) {
			if(list.isEmpty() || list.getLast().end<interval.start) {
				list.add(interval);
			}else {
				list.getLast().end = Math.max(list.getLast().end, interval.end);
			}
		}
		return list;
    }
}
class Solution {
    public List<Interval> merge(List<Interval> intervals) {
        /**
        按区间start排序, 依次判断排序后的每个区间, 如果返回区间中的最后一个区间的end
        大于等于当前区间的start, 更新最后一个区间的end, 否则直接添加入返回值中. 
        **/
        LinkedList<Interval> ret = new LinkedList<>();
        Collections.sort(intervals, (a, b) -> (a.start - b.start));
        for(Interval temp : intervals) {
            if(ret.isEmpty() || ret.peekLast().end < temp.start)
                ret.add(temp);
            else
                ret.peekLast().end = Math.max(ret.peekLast().end, temp.end);
        }
        return ret; 
    }
}

猜你喜欢

转载自blog.csdn.net/TQCAI666/article/details/87924159