力扣练习4(十题)
Posted 冷血~多好
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣练习4(十题)相关的知识,希望对你有一定的参考价值。
1.(412) Fizz Buzz
给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中:
answer[i] == "FizzBuzz" 如果 i 同时是 3 和 5 的倍数。
answer[i] == "Fizz" 如果 i 是 3 的倍数。
answer[i] == "Buzz" 如果 i 是 5 的倍数。
answer[i] == i 如果上述条件全不满足。
例 1:
输入:n = 3
输出:["1","2","Fizz"]
示例 2:输入:n = 5
输出:["1","2","Fizz","4","Buzz"]
示例 3:输入:n = 15
输出:["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"]
提示:
1 <= n <= 104
class Solution {
public List<String> fizzBuzz(int n) {
List<String> list=new ArrayList<>();
for(int i=1;i<=n;i++){
if(i%3==0&&i%5==0){
list.add("FizzBuzz");
}
else if(i%3==0){
list.add("Fizz");
}
else if(i%5==0){
list.add("Buzz");
}
else {
list.add(String.valueOf(i));
}
}
return list;
}
}
2. 剑指 Offer II 069. 山峰数组的顶部
符合下列属性的数组 arr 称为 山峰数组(山脉数组) :
arr.length >= 3
存在 i(0 < i < arr.length - 1)使得:
arr[0] < arr[1] < ... arr[i-1] < arr[i]
arr[i] > arr[i+1] > ... > arr[arr.length - 1]
给定由整数组成的山峰数组 arr ,返回任何满足 arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1] 的下标 i ,即山峰顶部。
示例 1:
输入:arr = [0,1,0]
输出:1
示例 2:输入:arr = [1,3,5,4,2]
输出:2
示例 3:输入:arr = [0,10,5,2]
输出:1
示例 4:输入:arr = [3,4,5,1]
输出:2
示例 5:输入:arr = [24,69,100,99,79,78,67,36,26,19]
输出:2
提示:
3 <= arr.length <= 104
0 <= arr[i] <= 106
题目数据保证 arr 是一个山脉数组
class Solution {
public int peakIndexInMountainArray(int[] arr) {
int n=0;
int n2=0;
for(int i=1;i<arr.length;i++){
if(n<=arr[i]){
n2=i;
n=arr[i];
}
else{
break;
}
}
return n2;
}
}
3.(17) 电话号码的字母组合
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:输入:digits = ""
输出:[]
示例 3:输入:digits = "2"
输出:["a","b","c"]
提示:
0 <= digits.length <= 4
digits[i] 是范围 ['2', '9'] 的一个数字。
class Solution {
public List<String> letterCombinations(String digits) {
List<List<String>> lists=new ArrayList<>();
List<String> list=new ArrayList<>();
list.add("a");list.add("b");list.add("c");lists.add(list);list= new ArrayList<>();
list.add("a");list.add("b");list.add("c");lists.add(list);list= new ArrayList<>();
list.add("a");list.add("b");list.add("c");lists.add(list);list= new ArrayList<>();
list.add("d");list.add("e");list.add("f");lists.add(list);list= new ArrayList<>();
list.add("g");list.add("h");list.add("i");lists.add(list);list= new ArrayList<>();
list.add("j");list.add("k");list.add("l");lists.add(list);list= new ArrayList<>();
list.add("m");list.add("n");list.add("o");lists.add(list);list= new ArrayList<>();
list.add("p");list.add("q");list.add("r");list.add("s");lists.add(list);list= new ArrayList<>();
list.add("t");list.add("u");list.add("v");lists.add(list);list= new ArrayList<>();
list.add("w");list.add("x");list.add("y");list.add("z");lists.add(list);
// for(int i=0;i<lists.size();i++){
// list= lists.get(i);
// for(int j=0;j<list.size();j++){
// System.out.println(list.get(j));
// }
// }
List<String> list0=new ArrayList<>();
if(digits.length()>0&&digits.length()<=1){
list=lists.get(Integer.parseInt(String.valueOf(digits.charAt(0))));
for(int i=0;i<list.size();i++){
list0.add(list.get(i));
}
}
else if(digits.length()>1&&digits.length()<=2){
list=lists.get(Integer.parseInt(String.valueOf(digits.charAt(0))));
for(int i=0;i<list.size();i++){
String s=list.get(i);
List<String> list2=lists.get(Integer.parseInt(String.valueOf(digits.charAt(1))));
for(int j=0;j<list2.size();j++){
list0.add(s+list2.get(j));
//["ad","ae","af","bd","be","bf","cd","ce","cf"]
}
}
}
else if(digits.length()>2&&digits.length()<=3){
list=lists.get(Integer.parseInt(String.valueOf(digits.charAt(0))));
for(int i=0;i<list.size();i++){
String s=list.get(i);
List<String> list2=lists.get(Integer.parseInt(String.valueOf(digits.charAt(1))));
for(int j=0;j<list2.size();j++){
String s2=list2.get(j);
List<String> list3=lists.get(Integer.parseInt(String.valueOf(digits.charAt(2))));
for(int k=0;k<list3.size();k++){
list0.add(s+s2+list3.get(k));
}
}
}
}
else if(digits.length()>3&&digits.length()<=4){
list=lists.get(Integer.parseInt(String.valueOf(digits.charAt(0))));
for(int i=0;i<list.size();i++){
String s=list.get(i);
List<String> list2=lists.get(Integer.parseInt(String.valueOf(digits.charAt(1))));
for(int j=0;j<list2.size();j++){
String s2=list2.get(j);
List<String> list3=lists.get(Integer.parseInt(String.valueOf(digits.charAt(2))));
for(int k=0;k<list3.size();k++){
String s3=list3.get(k);
List<String> list4=lists.get(Integer.parseInt(String.valueOf(digits.charAt(3))));
for(int p=0;p<list4.size();p++){
list0.add(s+s2+s3+list4.get(p));
}
}
}
}
}
return list0;
}
}
4.(24) 两两交换链表中的节点
/**
* 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 swapPairs(ListNode head) {
if(head==null||head.next==null){
return head;
}
ListNode list1=new ListNode();
ListNode list2=new ListNode();
ListNode list3=new ListNode();
ListNode list4=new ListNode();
ListNode head2=list4;
while(true){
if(head==null||head.next==null){
break;
}
list1=head;
list2=list1.next;
list3=list2.next;
list4.next=list2;
list2.next=list1;
list1.next=list3;
head=list3;
list4=list4.next.next;
// System.out.println(list4.val);
}
return head2.next;
}
}
5.(29) 两数相除
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
示例 2:输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2
提示:
被除数和除数均为 32 位有符号整数。
除数不为 0。
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。
class Solution {
int num=0;
public int divide(int dividend, int divisor) {
// 考虑被除数为最小值的情况
if (dividend == Integer.MIN_VALUE) {
if (divisor == 1) {
return Integer.MIN_VALUE;
}
if (divisor == -1) {
return Integer.MAX_VALUE;
}
}
// 考虑除数为最小值的情况
if (divisor == Integer.MIN_VALUE) {
return dividend == Integer.MIN_VALUE ? 1 : 0;
}
// 考虑被除数为 0 的情况
if (dividend == 0) {
return 0;
}
boolean b=false;
boolean b2=false;
boolean b3=false;
if(dividend>0){
dividend=-dividend;
b=true;
}
if(divisor>0){
divisor=-divisor;
b2=true;
}
if(dividend>divisor){
return 0;
}
if(dividend==Integer.MIN_VALUE){
dividend=dividend+1;
b3=true;
}
int m=add(dividend,divisor,0);
if(b3){
if((num-1)==divisor) {
m = m + 1;
}
}
if(b&&b2){
return m;
}
else if(b==false&&b2==false){
return m;
}
return -m;
}
public int add(int dividend, int divisor,int n){
int i=0;
int divisor2=0;
while (true){
divisor2=divisor<<i;
if(divisor2<dividend||divisor2>0){
divisor2=divisor<<(i-1);
while (divisor2>0){
i--;
divisor2=divisor<<(i-1);
}
break;
}
i++;
}
dividend=dividend-divisor2;
if(dividend>divisor){
num=dividend;
return (1<<i-1)+n;
}
return add(dividend,divisor,(1<<i-1))+n;
}
}
6.(34) 在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:
你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:输入:nums = [], target = 0
输出:[-1,-1]
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109。
class Solution {
public int[] searchRange(int[] nums, int target) {
boolean b1=false;
boolean b2=false;
int n[]=new int[2];
for(int i=0;i<nums.length;i++){
if(nums[i]==target){
n[0]=i;
b1=true;
break;
}
}
for(int i=nums.length-1;i>=0;i--){
if(nums[i]==target){
n[1]=i;
b2=true;
break;
}
}
if(b1&&b2){
return n;
}
n[0]=-1;
n[1]=-1;
return n;
}
}
7.(38) 外观数列
给定一个正整数 n ,输出外观数列的第 n 项。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。
你可以将其视作是由递归公式定义的数字字符串序列:
countAndSay(1) = "1"
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
前五项如下:
1. 1
2. 11
3. 21
4. 1211
5. 111221
第一项是数字 1
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"
要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。
例如,数字字符串 "3322251" 的描述如下图:
class Solution {
static String num[]=new String[30];
static int sum2=1;
static {
num[0]="1";
sum("1");
}
public String countAndSay(int n) {
return num[n-1];
}
public static void sum(String s){
char s1 = 0;
StringBuilder stringBuilder=new StringBuilder();
int k=0;
for(int i=0;i<s.length();i++){
if(i==0){
s1=s.charAt(i);
if(s.length()==1){
stringBuilder.append(String.valueOf(i+1)+s1);
}
}
else {
if(s1!=s.charAt(i)){
// s3=String.valueOf(i+1-k)+s1;
stringBuilder.append(String.valueOf(i-k)+s1);
s1=s.charAt(i);
k=i;
}
if(i==s.length()-1&&s1==s.charAt(i)){
stringBuilder.append(String.valueOf(i+1-k)+s1);
}
else if(i==s.length()-1&&s1!=s.charAt(i)){
stringBuilder.append(String.valueOf(i-k)+s.charAt(i));
}
}
}
num[sum2]=String.valueOf(stringBuilder);
if(sum2==29){
return;
}
sum2++;
sum( num[sum2-1]);
}
}
8.(211) 添加与搜索单词 - 数据结构设计
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 WordDictionary :
WordDictionary() 初始化词典对象
void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false 。word 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。
示例:
输入:
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
输出:
[null,null,null,null,false,true,true,true]解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // return False
wordDictionary.search("bad"); // return True
wordDictionary.search(".ad"); // return True
wordDictionary.search("b.."); // return True
提示:
1 <= word.length <= 500
addWord 中的 word 由小写英文字母组成
search 中的 word 由 '.' 或小写英文字母组成
最多调用 50000 次 addWord 和 search
class WordDictionary {
HashMap<Integer, Set<String>> map;
public WordDictionary() {
map = new HashMap<>();
}
public void addWord(String word) {
int n=word.length();
if(map.get(n)!=null){
map.get(n).add(word);
}
else {
Set<String> s=new HashSet<>();
s.add(word);
map.put(n,s);
}
}
public boolean search(String word) {
int k=0;
Set<String> s=map.get(word.length());
if(s== null){
return false;
}
for(String s2:s){
for(int j=0;j<word.length();j++){
if(word.charAt(j)!='.'&&s2.charAt(j)!=word.charAt(j)){
k++;
break;
}
}
if(k==0){
return true;
}
k=0;
}
return false;
}
}
/**
* Your WordDictionary object will be instantiated and called as such:
* WordDictionary obj = new WordDictionary();
* obj.addWord(word);
* boolean param_2 = obj.search(word);
*/
9.( 71) 简化路径
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。
请注意,返回的 规范路径 必须遵循下述格式:
始终以斜杠 '/' 开头。
两个目录名之间必须只有一个斜杠 '/' 。
最后一个目录名(如果存在)不能 以 '/' 结尾。
此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。
返回简化后得到的 规范路径
例 1:
输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。
示例 2:输入:path = "/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。
示例 3:输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
示例 4:输入:path = "/a/./b/../../c/"
输出:"/c"
提示:
1 <= path.length <= 3000
path 由英文字母,数字,'.','/' 或 '_' 组成。
path 是一个有效的 Unix 风格绝对路径。
class Solution {
public String simplifyPath(String path) {
String s[]=path.split("/");
Stack<String> stack=new Stack<>();
for(String str:s){
if(str.equals("")||str.equals(".")){
continue;
}
if(str.equals("..")){
if(!stack.empty())
stack.pop();
}else {
stack.push(str);
}
}
return "/"+String.join("/",stack);
}
}
10.(217) 存在重复元素
给定一个整数数组,判断是否存在重复元素。
如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。
示例 1:
输入: [1,2,3,1]
输出: true
示例 2:
输入: [1,2,3,4]
输出: false
示例 3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true
class Solution {
public boolean containsDuplicate(int[] nums) {
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if((i+1<nums.length)&&nums[i]==nums[i+1]){
return true;
}
}
return false;
}
}
。
以上是关于力扣练习4(十题)的主要内容,如果未能解决你的问题,请参考以下文章