Java基本算法(附上代码)

Java io流实现文件的复制

public class FileCopy {
    public static void main(String[] args) throws IOException {
        // 1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
        FileInputStream fis  = new FileInputStream("H:\\1.jpg");
        // 2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
        FileOutputStream fos = new FileOutputStream("G:\\1.jpg");

        // 使用缓冲读取多个字节,读多个字节写多个字节
        byte[] bytes = new byte[1024];
        int len = 0;// 每次读取的有效字节个数
        // 3.使用字节输入流对象中的方法read读取文件
        while((len = fis.read(bytes)) != -1){
            // 4. 使用字符输出流的方法write,把读到的字节写入目的地文件中
            fos.write(bytes,0,len);
        }
        // 5.释放资源(先关写的,后关闭的的;如果写完了,肯定读完毕了)
        fos.close();
        fis.close();
    }
}
public static void main(String[] args) throws IOException {

		//1.创建读入流与写出流并关联对应的文件
		FileReader fileReader = new FileReader("src/com\\qianfeng\\test\\Demo1.java");
		FileWriter fileWriter = new FileWriter("temp3.txt");
		
		//2.读写
		//一次多多个字符
//		char[] arr = new char[10];
//		int num;
//		while ((num = fileReader.read(arr)) != -1) {
//			//将字符数组的部分内容写入文件
//			fileWriter.write(arr, 0, num);
//		}
		
		//一次读一个字符
		int num;
		while ((num = fileReader.read()) != -1) {
			fileWriter.write(num);//自带了编码
		}
		
		//3.关闭资源
		fileReader.close();
		fileWriter.close();
	
	}

冒泡排序

将一个列表里的两个元素进行比较,并将最小的元素交换到顶部,从最底部的元素开始比较,两个元素中较小的会冒到顶部,而比较大的会沉到底部,该过程重复执行,达到排序效果(从大到小)。(从小到大也可以)

public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] arrs1= {1,3,4,2,8,5,7,6,3};
		int temp=0;//定义一个中间值用于交换
		//定义循环排序次数为arrs.length-1(因为10个数,两两相比,要比10-1次)
               //表示第i+1趟
		for (int i=0;i<arrs1.length-1;i++) {
		        //内部循环代表每次拿一个值向后比较,需要比较arrs.length-1-i次
                        //表示第几趟中的j+1次比较
			for (int j = 0; j < arrs1.length-1-i; j++) {
				//向后比较,只要大于就交换,循环一次完毕导致最大到数排在最后
				if(arrs1[j]>arrs1[j+1]) {
					//交换过程
					temp=arrs1[j];
					arrs1[j]=arrs1[j+1];
					arrs1[j+1]=temp;
				}
			}
			System.out.println(Arrays.toString(arrs1));
		}
	}

两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for(int i = 0;i<nums.length;i++){
            for(int j = 0;i< nums.length;j++){
                if(nums[j] == target - nums[i]){
                    return new int[]{i,j};
                }
            }
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}

整数反转

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例 :123 321

int reverse(int x){
    int max = 0x7fffffff, min = 0x80000000;//int的最大值最小值
    long temp=0;
    while(x!=0)
    {
        temp=temp*10+x%10;//%求余运算,如果被除数比除数小,商是0,余数就是被除数本身。 
        x/=10;
    }
    
    if(temp>max||temp<min)
    {
        return 0;
    }
    else
    {
        return (int)temp;
    }
}

罗马数字转整数(OOCL)

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

实例:输入III 输出3
public int romanToInt(String s) {
		int n = s.length();
		int roman_int = 0;
		for(int i=0;i<n;i++)
		{
			switch(s.charAt(i)) 
			{
			case 'I' : roman_int = roman_int + 1;break;
			case 'V' : roman_int = roman_int + 5;break;
			case 'X' : roman_int = roman_int + 10;break;
			case 'L' : roman_int = roman_int + 50;break;
			case 'C' : roman_int = roman_int + 100;break;
			case 'D' : roman_int = roman_int + 500;break;
			case 'M' : roman_int = roman_int + 1000;break;
			default: System.out.println("default");break;
			}

			if(i!=0)
			{
				if(((s.charAt(i)=='V')||(s.charAt(i)=='X'))&&(s.charAt(i-1)=='I')) 
					roman_int = roman_int-1*2;
				if(((s.charAt(i)=='L')||(s.charAt(i)=='C'))&&(s.charAt(i-1)=='X'))
					roman_int = roman_int-10*2;
				if(((s.charAt(i)=='D')||(s.charAt(i)=='M'))&&(s.charAt(i-1)=='C'))
					roman_int = roman_int-100*2;
			}
		}
		return roman_int;
	}

最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

实例:输入:abcd,abcf,abr;输出:ab

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs.length<1)return "";
        if(strs.length==1)return strs[0];
        StringBuilder result=new StringBuilder();
        Arrays.sort(strs);
        String first=strs[0];
        String end=strs[strs.length-1];
        for(int i=0;i<first.length();i++){
            if(first.charAt(i)==end.charAt(i))
                result.append(first.charAt(i));
            else break;
        }
        return result.toString();
    }
}

反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

class Solution {
    public String reverseString(String s) {
        int i = 0;
        int j = s.length()-1;
        char[] ch = s.toCharArray();
        while(i<j){
            swap(ch,i,j);
            i++;
            j--;
        }
        return new String(ch);
    }
    public void swap(char[] ch,int i,int j){
        char temp = ch[i];
        ch[i] = ch[j];
        ch[j] = temp;
    }
}

删除链表倒数第n个节点(OOCL)

给定一个链表,删除链表的倒数第 个节点,并且返回链表的头结点。

给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.

一次遍历的方法,但使用了一个额外的map空间来存储遍历的各个节点及其位置。空间上可以进一步优化,也就是不使用额外的map。而是使用两个节点,一个是first一个是second。先让first走n步,然后再让first和second同时往前走,当first走到头时,second即是倒数第n+1个节点了。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode temp = head;
        Map<Integer,ListNode> m = new HashMap<Integer,ListNode>();
        int index=1;
        while(temp!=null){
            m.put(index++,temp);
            temp = temp.next;
        }
        int size = m.size();
        if(size == 1)
            return null;
        if(n == 1){
            m.get(size-1).next = null;
        }else if(n == size){
            head = head.next;
        }else{
            m.get(size-n).next = m.get(size-n+2);
        }
        return head;
    }
}

缺失的第一个正整数(CVTE)

给定一个未排序的整数数组,找出其中没有出现的最小的正整数。

class Solution {
    public int firstMissingPositive(int[] nums) {
        Arrays.sort(nums);
        
        int target = 1;
        for(int i=0; i < nums.length; i++) {
            if(nums[i] <= 0) {
                continue;
            }
            if(nums[i] > target) {
                return target;
            }
            if(nums[i] == target) {
                target += 1;
                continue;
            }
        }
        return target;
    }
}```

LRU缓存机制(CVTE)

运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。

获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。 
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。

LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // 返回  1
cache.put(3, 3);    // 该操作会使得密钥 2 作废
cache.get(2);       // 返回 -1 (未找到)
cache.put(4, 4);    // 该操作会使得密钥 1 作废
cache.get(1);       // 返回 -1 (未找到)
cache.get(3);       // 返回  3
cache.get(4);       // 返回  4

public LRUCache(int capacity) {
        size = capacity;     //长度 限制 三个参数没写 
        map = new HashMap<Integer, Integer>();
        list = new LinkedList<Integer>();
    }
 public int get(int key) {
         Integer temp = map.get(key);
        if (temp == null) {
            return -1;
        }
        list.remove((Integer) key);
        list.add(key);
        return temp;
    }
 public void put(int key, int value) {
        if (map.get(key) != null) {
            map.put(key, value);
            list.remove((Integer) key);
            list.add(key);
        }else  {
            if (size != map.size()) {
                list.add(key);
                map.put(key, value);
            } else {
                Integer x = list.get(0);
                map.remove(x);
                list.remove(0);
                map.put(key, value);
                list.add(key);
            }
        } 
    }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值