上机

1,罗马数字转十进制

描述:

罗马数字包含以下七种字符: IVXLCDM

字符          数值
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 的范围内。

示例 1:

输入: "III"
输出: 3

示例 2:

输入: "IV"
输出: 4

示例 3:

输入: "IX"
输出: 9

示例 4:

输入: "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.

示例 5:

输入: "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.

leedcode 13

解答:

public class LeedCode13 {
    private static HashMap<Character,Integer> map = new HashMap<>();
    static {
        map.put('I',1);
        map.put('V',5);
        map.put('X',10);
        map.put('L',50);
        map.put('C',100);
        map.put('D',500);
        map.put('M',1000);
    }
    public static void main(String[] args) {
        System.out.println(romanToInt("III"));//3
        System.out.println(romanToInt("IV"));//4
        System.out.println(romanToInt("IX"));//9
        System.out.println(romanToInt("LVIII"));//58
        System.out.println(romanToInt("MCMXCIV"));//1994
    }
    public static int romanToInt(String s) {
        int result = 0;
        int a = 0;
        int i = 0;
        for( ; i < s.length() - 1; i ++){
            a = map.get(s.charAt(i));
            if(a < map.get(s.charAt(i + 1))){
                result -= a;
            }else {
                result += a;
            }
        }
        result += map.get(s.charAt(i));
        return result;
    }
}

2,输出target的值

​ 输入一个递增排序的数组nums和一个数字target (数组nums中的数字和target的数值均为整数),在数组中查找两个数,使得它们的差正好是target。如果有多对数字的和等于target,输出全部组合。

要求: 要考虑时间复杂度和空间复杂度

如果数组中不存在目标值,返回 [-1, -1]

示例 1:

输入:nums = [1,2,4,7,8,11,15], target = 15

输出: [4,11], [7,8]

示例 2:

输入: nums = [5,7,9,10,13], target = 7

输出: [-1,-1]

解答:

//时间复杂度为O(n)
public class Test {
    public static void main(String[] args) {
        int array1[] = { 1, 2, 4, 7, 8, 11, 15 };
        int array2[] = { 5,7,9,10,13 };
        function(array1,15);
        function(array2,7);
    }
    public static void function(int[] data,int sum){
        boolean flag = true;
        int left = 0;
        int right = data.length -1;
        while(left <= right){
            if(data[left] + data[right] == sum){
                flag = false;
                System.out.print("["+data[left] + "," + data[right]+"]  ");
                left --;
                right --;
                continue;
            }else if(data[left] + data[right] >sum)
                right --;
            else
                left ++;
        }
        if(flag){
            System.out.print("[-1,-1]");
        }
        System.out.println();
    }
}

3,判断链表是否为回文结构

​ 给定一个单链表(无环),请判断是否是回文结构。在删除倒数第K个节点后,是否为回文结构。(回文结构:从头到尾遍历节点的值序列结果,与从尾到头遍历的值序列结果是一样的)

要求: 要考虑时间复杂度和空间复杂度

示例 1:

输入: 1->8->4->4->8->1, K=3

输出: true, true

示例 2:

输入: 1->2->5->2->1, K=2

输出: true, false

示例 3:

输入: 1->2->5->3->2->1, K=3

输出: false, true

解答:

public class Test2 {
    //经过分析,平行的遍历链表2次,2次都是遍历一半,时间复杂度为 O(n)。占用的空间为链表长度的一半,空间复杂度为O(n)
    public static void main(String[] args) {
        int[] temp1 = {1,8,4,4,8,1};
        Node head1 = init(temp1);
        isPalindrome(head1,3);

        int[] temp2 = {1,2,5,2,1};
        Node head2 = init(temp2);
        isPalindrome(head2,2);

        int[] temp3 = {1,2,5,3,2,1};
        Node head3 = init(temp3);
        isPalindrome(head3,3);
    }
    public static class Node {//不带头节点
        public int value;
        public Node next;

        public Node(int data) {
            this.value = data;
        }
    }
    public static void isPalindrome(Node head, int k) {
        boolean a = isPalindrome(head);
        Node p = head;
        delete(head,k);
        boolean b = isPalindrome(head);
        System.out.println(a + " " + b);
    }
    //初始化一个链表
    public static Node init(int[] values){
        if(values != null &&values.length > 0){
            Node head = new Node(values[0]);
            Node p = head;
            for(int i = 1; i < values.length ; i ++){
                p.next = new Node(values[i]);
                p = p.next;
            }
            return head;
        }
        return null;
    }
    //删除第k个节点,按照示例的意思,应该是从1开始
    public static void delete(Node head, int k) {
        if (k < 1) return;
        if (k == 1) {
            if(head.next != null){
                head = head.next;
            }
        }else {
            Node front = null;
            Node p = head;
            for(int i = 1; i < k && p.next != null; i ++, p = p.next){
                front = p;
            }
            front.next = p.next;
        }
    }
    //使用快慢指针
    public static boolean isPalindrome(Node head) {
        if (head == null || head.next == null) return true;
        //这样可以确保慢速的指针肯定在中间,或中间偏右。可以画图
        Node low = head.next; //慢指针
        Node fast = head;//快指针
        while (fast.next != null && fast.next.next != null) {
            low = low.next;
            fast = fast.next.next;
        }
        Stack<Node> stack = new Stack<Node>();
        while (low != null) {
            stack.push(low);
            low = low.next;
        }
        Node p = head;
        while (!stack.isEmpty()) {
            if (p.value != stack.pop().value) {
                return false;
            }
            p = p.next;
        }
        return true;
    }
}

4,leedcode7

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

示例 1:

输入: 123
输出: 321

示例 2:

输入: -123
输出: -321

示例 3:

输入: 120
输出: 21

注意:

假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

解题:

public class Leedcode7 {
	public static int MAX_VALUE = Integer.MAX_VALUE;
	public static int MIN_VALUE = Integer.MIN_VALUE;

	//占用内存或耗时较多
	public static int reverse(int x) {
		String data = x + "";
		String res = "";
		int min = x >= 0 ? 0 : 1;
		for (int i = data.length() - 1; i >= min; i--) {
			res += data.charAt(i);
		}
		long a = Long.parseLong(res);
		if (x < 0)
			a *= -1;
		if (a > MAX_VALUE || a < MIN_VALUE)
			return 0;
		return (int) a;
	}
	//评论区解法算法
	public static int reverse1(int x) {
		long res = 0;
		while(x != 0) {
			res = res * 10 + x % 10;
			x /= 10;
		}
		return (int)res == res ? (int)res : 0;
	}
}

5,leedcode15

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

解法:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Leedcode15 {
	public static void main(String[] args) {

		System.out.println(Arrays.asList(1,2,3).equals(Arrays.asList(3,2,1)));
	}

	//这种解法超时 自己想的解法
	public static List<List<Integer>> threeSum(int[] nums) {
		List<List<Integer>> res = new ArrayList<>();
		for(int i = 0; i < nums.length;i ++) {
			for(int j = i + 1; j < nums.length; j ++) {
				for(int k = j + 1; k < nums.length; k ++) {
					if(nums[i] + nums[j] + nums[k] == 0) {
						add(res,Arrays.asList(nums[i],nums[j],nums[k]));
					}
				}
			}
		}
		return res;
    }
	private static void add(List<List<Integer>> res, List<Integer> asList) {
		System.out.println(asList);
		boolean flag = true;
		for(List<Integer> list : res) {
			if(list.containsAll(asList) && asList.containsAll(list)) {
				flag = false;
				break;
			}
		}
		if(flag)
			res.add(asList);
	}
	
	//评论区解法
	public static List<List<Integer>> threeSum1(int[] nums){
		List<List<Integer>> res = new ArrayList<>();
		Arrays.sort(nums);
		
		for(int i = 0; i < nums.length - 2; i ++) {
			if(i == 0 || nums[i] != nums[i - 1]) {
				int wantedNum = 0 - nums[i]; //想要的另外两个值
				int left = i + 1;
				int right = nums.length - 1;
				while(left < right) {
					if(nums[left] + nums[right] == wantedNum) {
						res.add(Arrays.asList(nums[i],nums[left],nums[right]));
						while(left < right && nums[left] == nums[left + 1]) left ++;
						while(left < right && nums[right] == nums[right - 1]) right --;
						left ++;
						right --;
					}else if(nums[left] + nums[right] > wantedNum){
						while(left < right && nums[right] == nums[right - 1]) right --;
						right --;
					}else if(nums[left] + nums[right] < wantedNum) {
						while(left < right && nums[left] == nums[left + 1]) left ++;
						left ++;
					}
				}
			}
		}
		return res;
	}
}

6,leedcode3

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

解答:

public class leedcode3 {
	
	public static void main(String[] args) {
		System.out.println(lengthOfLongestSubstring("abcabcbb"));//3
		System.out.println(lengthOfLongestSubstring("bbbbb"));//1
		System.out.println(lengthOfLongestSubstring("pwwkew"));//3
		System.out.println(lengthOfLongestSubstring("aab"));//2
		System.out.println(lengthOfLongestSubstring("dvdf"));//3
	}
	
	public static int lengthOfLongestSubstring(String s) {
		StringBuffer cap = new StringBuffer();//cap的作用是收集,不重子串
		List<Integer> weights = new ArrayList<>();
		for(int i = 0; i < s.length(); i ++) {
			String temp = cap.toString();
			int index = temp.indexOf(s.charAt(i) + "");
			if(index != -1) { //发现了重复
				weights.add(cap.length());//发现了重复 ,将当前不重复字串的长度记录以下
				cap.setLength(0);//清空cap
				cap.append(temp.substring(index + 1));//将从字串重复的位置阶段,后面是不重复的字串
				cap.append(s.charAt(i));
			}else {
				cap.append(s.charAt(i));
			}
		}
		weights.add(cap.length());
		weights.sort(new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return o2 - o1;
			}
		});
		return weights.get(0);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值